F77_LOGICAL_FUNCTION(ast_isapolygon)( INTEGER(THIS), INTEGER(STATUS) ) { GENPTR_INTEGER(THIS) F77_LOGICAL_TYPE(RESULT); astAt( "AST_ISAPOLYGON", NULL, 0 ); astWatchSTATUS( RESULT = astIsAPolygon( astI2P( *THIS ) ) ? F77_TRUE : F77_FALSE; ) return RESULT;
int *smf_jsatiles_region( AstRegion *region, smfJSATiling *skytiling, int *ntile, int *status ){ /* Local Variables */ AstFrameSet *fs; AstKeyMap *km; AstRegion *region2; AstRegion *space_region; AstRegion *tregion; AstSkyFrame *skyframe; char text[ 200 ]; const char *key; double *mesh = NULL; double *xmesh; double *ymesh; int *tiles = NULL; int axes[ 2 ]; int i; int ineb; int itile2; int itile; int ix; int iy; int key_index; int lbnd[ 2 ]; int mapsize; int npoint; int old_sv; int overlap; int ubnd[ 2 ]; int value; int xoff[ 4 ] = { -1, 0, 1, 0 }; int xt; int yoff[ 4 ] = { 0, 1, 0, -1 }; int yt; /* Initialise */ *ntile = 0; /* Check inherited status */ if( *status != SAI__OK ) return tiles; /* Start an AST context so that all AST objects created in this function are annulled automatically. */ astBegin; /* Identify the celestial axes in the Region. */ atlFindSky( (AstFrame *) region, &skyframe, axes + 1, axes, status ); /* Report an error if no celestial axes were found. */ if( !skyframe && *status == SAI__OK ) { space_region = NULL; *status = SAI__ERROR; errRep( "", "The current WCS Frame in the supplied Region or " "NDF does not include celestial longitude and latitude axes.", status ); /* Otherwise, if the Region itself is 2-dimensional, it does not contain any other axes, so just use it as is. */ } else if( astGetI( region, "Naxes" ) == 2 ) { space_region = astClone( region ); /* Otherwise, create a new Region by picking the celestial axes from the supplied Region. Report an error if a Region cannot be created in this way. */ } else { space_region = astPickAxes( region, 2, axes, NULL ); if( !astIsARegion( space_region ) && *status == SAI__OK ) { *status = SAI__ERROR; errRep( "", "The celestial longitude and latitude axes in the " "supplied Region or NDF are not independent of the other " "axes.", status ); } } /* Create a FrameSet describing the whole sky in which each pixel corresponds to a single tile in SMF__JSA_HPX projection. The current Frame is ICRS (RA,Dec) and the base Frame is grid coords in which each grid pixel corresponds to a single tile. */ smf_jsatile( -1, skytiling, 0, SMF__JSA_HPX, NULL, &fs, NULL, lbnd, ubnd, status ); /* Map the Region using the FrameSet obtained above so that the new Region describes offsets in tiles from the lower left tile. If "space_region" is a Polygon, ensure that the SimpVertices attribute is set so that the simplify method will take non-linearities into account (such as the region being split by the RA=12h meridian). */ astInvert( fs ); fs = astConvert( space_region, fs, "SKY" ); if( !fs && *status == SAI__OK ) { *status = SAI__ERROR; errRep( "", "Cannot convert the supplied Region to ICRS.", status ); goto L999; } old_sv = -999; if( astIsAPolygon( space_region ) ){ if( astTest( space_region, "SimpVertices" ) ) { old_sv = astGetI( space_region, "SimpVertices" ); } astSetI( space_region, "SimpVertices", 0 ); } region2 = astMapRegion( space_region, fs, fs ); if( astIsAPolygon( space_region ) ){ if( old_sv == -999 ) { astClear( space_region, "SimpVertices" ); } else { astSetI( space_region, "SimpVertices", old_sv ); } } /* Get a mesh of all-sky "grid" positions (actually tile X and Y indices) covering the region. Since the mesh positions are limited in number and placed arbitrarily within the Region, the mesh will identify some, but potentially not all, of the tiles that overlap the Region. */ astGetRegionMesh( region2, 0, 0, 2, &npoint, NULL ); mesh = astMalloc( 2*npoint*sizeof( *mesh ) ); astGetRegionMesh( region2, 0, npoint, 2, &npoint, mesh ); /* Find the index of the tile containing each mesh position, and store them in a KeyMap using the tile index as the key and "1" (indicating the tile overlaps the region) as the value. The KeyMap is sorted by age of entry. Neighbouring tiles will be added to this KeyMap later. If an entry has a value of zero, it means the tile does not overlap the supplied Region. If the value is positive, it means the tile does overlap the supplied Region. If the value is negative, it means the tile has not yet been tested to see if it overlaps the supplied Region. */ km = astKeyMap( "SortBy=KeyAgeDown" ); xmesh = mesh; ymesh = mesh + npoint; for( i = 0; i < npoint && *status == SAI__OK; i++ ) { ix = (int)( *(xmesh++) + 0.5 ) - 1; iy = (int)( *(ymesh++) + 0.5 ) - 1; itile = smf_jsatilexy2i( ix, iy, skytiling, status ); if (itile != VAL__BADI) { sprintf( text, "%d", itile ); astMapPut0I( km, text, 1, NULL ); } } /* Starting with the oldest entry in the KeyMap, loop round checking all entries, in the order they were added, until all have been checked. Checking an entry may cause further entries to be added to the end of the KeyMap. */ key_index = 0; mapsize = astMapSize( km ); while( key_index < mapsize && *status == SAI__OK ) { key = astMapKey( km, key_index++ ); /* Convert the key string to an integer tile index. */ itile = atoi( key ); /* Get the integer value associated with the tile. */ astMapGet0I( km, key, &value ); /* If the tile associated with the current KeyMap entry has not yet been tested for overlap with the requested Region (as shown by the entry value being -1), test it now. */ if( value == -1 ) { /* Get a Region covering the tile. */ smf_jsatile( itile, skytiling, 0, SMF__JSA_HPX, NULL, NULL, &tregion, lbnd, ubnd, status ); /* See if this Region overlaps the user supplied region. Set the value of the KeyMap entry to +1 or 0 accordingly. */ overlap = astOverlap( tregion, space_region ); if( overlap == 0 ) { if( *status == SAI__OK ) { *status = SAI__ERROR; errRep( "", "Cannot align supplied Region with the sky " "tile coordinate system (programming error).", status ); } } else if( overlap == 1 || overlap == 6 ) { value = 0; } else { value = 1; } astMapPut0I( km, key, value, NULL ); } /* Skip the current KeyMap entry if the corresponding tile does not overlap the requested Region (as shown by the entry value being zero). */ if( value == 1 ) { /* The current tile overlaps the supplied Region, so add the tile index to the returned list of tile indices. */ tiles = astGrow( tiles, ++(*ntile), sizeof( *tiles ) ); if( *status == SAI__OK ) { tiles[ *ntile - 1 ] = itile; /* Add the adjoining tiles to the end of the KeyMap so that they will be tested in their turn, giving them a value of -1 to indicate that they have not yet been tested to see if they overlap the supplied Region. Ignore adjoining tiles that are already in the keyMap. */ smf_jsatilei2xy( itile, skytiling, &xt, &yt, NULL, status ); for( ineb = 0; ineb < 4; ineb++ ) { itile2 = smf_jsatilexy2i( xt + xoff[ ineb ], yt + yoff[ ineb ], skytiling, status ); if( itile2 != VAL__BADI ) { sprintf( text, "%d", itile2 ); if( !astMapHasKey( km, text ) ) { astMapPut0I( km, text, -1, NULL ); mapsize++; } } } } } } /* Arrive here if an error occurs. */ L999:; /* Free resources. */ mesh = astFree( mesh ); if( *status != SAI__OK ) { tiles = astFree( tiles ); *ntile = 0; } astEnd; return tiles; }