Changeset 24853
- Timestamp:
- 05/13/20 23:17:49 (5 years ago)
- Location:
- issm/trunk-jpl/src/m/contrib/larour
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/contrib/larour/glacier_inventory.m
r24851 r24853 16 16 shapefileroot = ''; 17 17 regions = struct(); 18 o2regions = struct(); 18 19 element_connectivity = []; 19 20 glacier_connectivity = []; … … 32 33 self.shapefileroot=getfieldvalue(options,'shapefileroot'); 33 34 self.region_names=getfieldvalue(options,'region_names'); 34 regions_zone_shapefile=getfieldvalue(options,'regions_zone_shapefile',''); 35 36 %region region zones first if available: 37 if ~strcmpi(regions_zone_shapefile,''), 38 region_zones=shpread(regions_zone_shapefile); 39 end 35 o2regions_shapefile=getfieldvalue(options,'o2regions_shapefile'); 36 37 %first read o2 regions shapefile: 38 self.o2regions=shpread(o2regions_shapefile); 40 39 41 40 %read the shape files and create the regions: … … 46 45 disp(['reading region: ' self.regions(i).name]); 47 46 self.regions(i).id=i; 48 self.regions(i).zone=[region_zones(i).x,region_zones(i).y];49 47 contours=shpread([self.shapefileroot '/' self.regions(i).name '.shp']); 50 48 … … 82 80 end 83 81 %}}} 82 function units(self) % {{{ 83 disp('Glacier inventory units: '); 84 disp(' areas: km^2'); 85 disp(' mass: Gt'); 86 87 end 88 %}}} 84 89 function counter = nglaciers(self,varargin) % {{{ 85 90 … … 135 140 function [lid,rid]=gidtolid(self,gid) % {{{ 136 141 [mpartition,npartition]=self.partition(); 142 lid=zeros(length(gid),1); 143 rid=zeros(length(gid),1); 137 144 for i=1:self.nregions(), 138 if (gid>=mpartition(i) && gid <=npartition(i)), 139 rid=i; 140 lid=gid-mpartition(i)+1; 141 break; 142 end 145 pos=find(gid>=mpartition(i) & gid<=npartition(i)); 146 rid(pos)=i; 147 lid(pos)=gid(pos)-mpartition(i)+1; 143 148 end 144 149 … … 154 159 for i=1:self.nregions(), 155 160 disp(sprintf(' region %i: ''%s'' %i glaciers ',i,self.regions(i).name,length(self.regions(i).Area))); 156 end157 158 end % }}}159 function connectivity_check(self,md) % {{{160 disp(sprintf(' Checking glacier connectivity:'));161 figure(1),clf,hold on;162 counter=0;163 164 %some quick checks: % {{{165 if ~isempty(find(self.glacier_connectivity>md.mesh.numberofelements)),166 error('glacier_connectivity table is pointing to elements that are > md.mesh.numberofelements!');167 end168 if ~isempty(find(self.glacier_connectivity<0)),169 error('glacier_connectivity table is pointing to elements that are < 0!');170 end %}}}171 172 for gid=1:length(self.glacier_connectivity),173 if mod(gid,1000)==0,174 disp(num2str(gid/length(self.glacier_connectivity)*100));175 end176 el=self.glacier_connectivity(gid); latel=md.mesh.lat(md.mesh.elements(el,:)); longel=md.mesh.long(md.mesh.elements(el,:));177 x1=latel(1); x2=latel(2); x3=latel(3);178 y1=longel(1); y2=longel(2); y3=longel(3);179 180 [lid,rid]=self.gidtolid(gid);181 x0=self.regions(rid).CenLat(lid);182 y0=self.regions(rid).CenLon(lid);183 184 if ~isintriangle(x0,x1,x2,x3,y0,y1,y2,y3),185 186 %check in local coordinate system:187 proj=laea(x0,y0);188 [xp,yp]=gdaltransform([y0,y1,y2,y3],[x0,x1,x2,x3],'EPSG:4326',proj);189 x0=xp(1); x1=xp(2); x2=xp(3); x3=xp(4);190 y0=yp(1); y1=yp(2); y2=yp(3); y3=yp(4);191 192 if ~isintriangle(x0,x1,x2,x3,y0,y1,y2,y3),193 194 plot([x1,x2,x3,x1],[y1,y2,y3,y1],'k*-'); text(x1,y1,'1'); text(x2,y2,'2'); text(x3,y3,'3'); plot(x0,y0,'r*');195 error(sprintf('Vertex %i in region %i and lid %i is not within element %i',gid,rid,lid,el));196 disp(sprintf('Vertex %i in region %i and lid %i is not within element %i',gid,rid,lid,el));197 counter=counter+1198 end199 end200 161 end 201 162 … … 268 229 %}}} 269 230 function mesh_connectivity(self,mesh) % {{{ 270 271 %initialize glacier and element connectivity: 272 glacier_connectivity=zeros(self.nglaciers,1); 231 232 plotr=1; 233 234 %The way we run this is through the O2 zones defined in o2regions. We go through 235 %these regions, figure out the centroid, figure out how many elements are close to 236 %this centroid (very important to do this through vertex lat,long, and not through elemnet 237 % lat,long which can be seriously warped because of the -180 to +180 longitude transition. 238 %We then project the region in lamber azimuthal equal area, along with glaciers and elements. 239 %Once projected, we figure out which glaciers belong to which element in the local 240 %projection system. 241 242 %initialize glacier connectivity: 243 self.glacier_connectivity=zeros(self.nglaciers,1); 273 244 274 245 %assume maximum width for connectivity table and initialize 275 246 %as sparse matrix: 276 ny=3000; 277 element_connectivity=sparse(mesh.numberofelements,ny); 247 ny=self.nglaciers(); self.element_connectivity=sparse(mesh.numberofelements,ny); 278 248 279 249 disp('Building element and glacier connectivity table: '); 280 250 281 partition_counter=0; 251 %O2 regions: 252 o1=zeros(self.nglaciers(),1); 253 o2=zeros(self.nglaciers(),1); 254 counter=1; 282 255 for i=1:self.nregions(), 283 256 region=self.regions(i); 284 285 disp([' region ' num2str(i) ': ' region.name]);286 287 %reproject on a lambert centered on the region:288 latel=mesh.lat(mesh.elements)*[1;1;1]/3;289 longel=mesh.long(mesh.elements)*[1;1;1]/3;290 257 for j=1:length(region.CenLat), 291 if mod(j,100)==0, 292 disp(num2str(j/length(region.CenLat)*100)); 293 end 294 295 lat0=region.CenLat(j); long0=region.CenLon(j); 296 %proj=laea(lat0,long0); 297 298 %to avoid folding of projections from behind the Earth, restrict ourselves 299 %to only locations around a lat,long radius around lat0,long0 300 list_elements=flaglatlongradius(latel,longel,lat0,long0,5); 301 302 %go through these elements and figure out if the glacier is inside: 303 found=0; 304 for k=1:length(list_elements), 305 el=list_elements(k); 306 lat=mesh.lat(mesh.elements(el,:)); 307 long=mesh.long(mesh.elements(el,:)); 308 x0=lat0; x1=lat(1); x2=lat(2); x3=lat(3); 309 y0=long0; y1=long(1); y2=long(2); y3=long(3); 310 311 if isintriangle(x0,x1,x2,x3,y0,y1,y2,y3), 312 %we have found the element where this glacier belongs: 313 found=1; 314 break; 315 end 316 end; 317 if ~found, %try again with a projection and all elements: % {{{ 318 proj=laea(lat0,long0); 319 list_elements=(1:mesh.numberofelements)'; 258 o1(counter)=region.O1Region(j); 259 o2(counter)=region.O2Region(j); 260 counter=counter+1; 261 end 262 end 263 264 %Go through O2 regions: 265 for i=1:length(self.o2regions), 266 string=self.o2regions(i).RGI_CODE; 267 disp(['progressing with region ' num2str(i) ' ' string]); 268 offset=findstr(string,'-'); 269 o1i=str2num(string(1:offset-1)); 270 o2i=str2num(string(offset+1:end)); 271 glaciers=find(o1==o1i & o2==o2i); 272 273 if ~isempty(glaciers), 274 %find lat,long for laea projection: 275 box=self.o2regions(i).BoundingBox; 276 long0=mean(box(:,1)); 277 lat0=mean(box(:,2)); 278 proj=laea(lat0,long0); 279 280 %find radius of box: 281 minlat=min(box(:,2)); maxlong=max(box(:,1)); 282 radius=sqrt( (lat0-minlat)^2+(long0-maxlong)^2); 283 284 %some radius adjustment: {{{ 285 switch i, 286 case 4, radius=40; 287 case 12, radius=25; 288 case 33, radius=5; 289 case 41, radius=75; 290 case 42, radius=45; 291 case 68, radius=10; 292 case 82, radius=30; 293 otherwise, 294 end % }}} 295 296 [lids,rids]=self.gidtolid(glaciers); 297 %quick check on the rids, should all be the same number: 298 if min(rids)~=max(rids)error(sprintf('rids should only span on O1 region')); end; 299 rid=max(rids); 300 301 region=self.regions(rid); 302 elements=flaglatlongradiuselements(mesh.elements,mesh.lat,mesh.long,lat0,long0,radius); 303 304 if plotr, % {{{ 305 figure(1),clf; 306 subplot(2,1,1),hold on; 307 trisurf(mesh.elements(elements,:),mesh.long,mesh.lat,mesh.lat),view(2); 308 plot3(box(1,1),box(1,2),1000,'r*','MarkerSize',10); 309 plot3(box(1,1),box(2,2),1000,'r*','MarkerSize',10); 310 311 plot3(box(2,1),box(1,2),1000,'r*','MarkerSize',10); 312 plot3(box(2,1),box(2,2),1000,'r*','MarkerSize',10); 313 314 plot3(region.CenLon(lids),region.CenLat(lids),1000*ones(length(lids),1),'k*'); 315 end % }}} 316 317 %project lat,long: 318 [x,y]=gdaltransform(mesh.long,mesh.lat,'EPSG:4326',proj); 319 [xlid,ylid]=gdaltransform(region.CenLon(lids),region.CenLat(lids),'EPSG:4326',proj); 320 321 if plotr, % {{{ 322 figure(1),subplot(2,1,2), hold on; 323 trisurf(mesh.elements(elements,:),x,y,x),view(2); 324 plot3(xlid,ylid,1000*ones(length(lids),1),'k*'); 325 pause(.1); 326 end % }}} 327 328 %go through lids: 329 for j=1:length(lids), 320 330 found=0; 321 [xp,yp]=gdaltransform([mesh.long;long0],[mesh.lat;lat0],'EPSG:4326',proj);322 x0=xp(end); y0=yp(end);323 for k=1:length(list_elements),324 el=list_elements(k);325 x =xp(mesh.elements(el,:)); y=yp(mesh.elements(el,:));326 x 1=x(1); x2=x(2); x3=x(3);327 y1=y(1); y2=y(2); y3=y(3); 331 x0=xlid(j); y0=ylid(j); 332 for k=1:length(elements), 333 el=elements(k); 334 x1=x(mesh.elements(el,1)); y1=y(mesh.elements(el,1)); 335 x2=x(mesh.elements(el,2)); y2=y(mesh.elements(el,2)); 336 x3=x(mesh.elements(el,3)); y3=y(mesh.elements(el,3)); 337 328 338 if isintriangle(x0,x1,x2,x3,y0,y1,y2,y3), 329 %we have found the element where this glacier belongs:330 339 found=1; 331 340 break; 332 341 end 333 end;334 end % }}}335 if ~found, %not found, plot %{{{336 figure(1),clf,hold on;337 plot(x0,y0,'r*');338 for k=1:length(list_elements),339 el=list_elements(k);340 x=xp(mesh.elements(el,:)); y=yp(mesh.elements(el,:));341 x1=x(1); x2=x(2); x3=x(3);342 y1=y(1); y2=y(2); y3=y(3);343 plot([x1,x2,x3,x1],[y1,y2,y3,y1],'k*-');344 342 end 345 error('cound not find an element, believe it or not'); %}}} 343 self.glacier_connectivity(glaciers(j))=el; 344 if ~found, 345 error(sprintf('could not find element for glacier %i with lid %i',j,lids(j))); 346 end 346 347 end 347 glacier_connectivity(partition_counter+j)=el; 348 end 349 partition_counter=partition_counter+length(region.CenLat); 350 end 351 352 %Now that we have all the elements for each glacier, we can build a 353 %connectivity table that is the reverse of the glacier connectivity table. 354 %For each element, this will tell us which glaciers belong to this element. 355 for j=1:length(glacier_connectivity), 356 el=glacier_connectivity(j); 357 count=element_connectivity(el,ny); 348 end 349 end 350 351 %build element connectivity table: 352 for j=1:length(self.glacier_connectivity), 353 el=self.glacier_connectivity(j); 354 count=self.element_connectivity(el,ny); 358 355 if count>ny, 359 error('need to enlarge connectivity table'); 360 end 361 element_connectivity(el,count+1)=j; 362 element_connectivity(el,ny)=count+1; 363 end 364 365 %Reduce the number of columns (we did not initially, so we chose an arbitrary ny: 366 nmax=max(element_connectivity(:,end)); 367 element_connectivity=element_connectivity(:,[1:nmax,ny]); 368 369 %Assign pointers: 370 self.element_connectivity=element_connectivity; 371 self.glacier_connectivity=glacier_connectivity; 372 373 end % }}} 356 error('need to enlarge connectivity table to at least'); 357 end 358 self.element_connectivity(el,count+1)=j; 359 self.element_connectivity(el,ny)=count+1; 360 end 361 362 %Reduce the number of columns (we did not initially, so we chose an arbitrary ny: 363 nmax=max(self.element_connectivity(:,end)); 364 self.element_connectivity=self.element_connectivity(:,[1:nmax,ny]); 365 366 367 end % }}} 368 function checkconnectivity(self,mesh) % {{{ 369 370 vector=find(self.element_connectivity(:,end)); 371 372 for i=1:length(vector), 373 el=vector(i); 374 375 flags=zeros(mesh.numberofelements,1); 376 flags(el)=1; 377 378 nglaciers=self.element_connectivity(el,end); 379 glaciers=self.element_connectivity(el,1:nglaciers); 380 381 [lids,rids]=self.gidtolid(glaciers); 382 lat=zeros(length(glaciers),1); 383 long=zeros(length(glaciers),1); 384 for j=1:nglaciers, 385 lat(j)=self.regions(rids(j)).CenLat(lids(j)); 386 long(j)=self.regions(rids(j)).CenLon(lids(j)); 387 end 388 389 proj=laea(lat(1),long(1)); 390 391 figure(1),clf,hold on; 392 [x,y]=gdaltransform(mesh.long(mesh.elements(el,:)),mesh.lat(mesh.elements(el,:)),'EPSG:4326',proj); 393 p=patch('XData',x,'YData',y); set(p,'FaceColor','red') 394 395 [x,y]=gdaltransform(long,lat,'EPSG:4326',proj); 396 plot(x,y,'k*'); 397 pause(.1); 398 end 399 400 end % }}} 401 374 402 end 375 403 end
Note:
See TracChangeset
for help on using the changeset viewer.