def query_segments(self, shape_id): self._current_shape_id = shape_id a = self.stop_class b = self.traffic_class rez = self.session.query( self.stop_class, self.traffic_class, func.ST_AsText( func.ST_ClosestPoint(func.ST_Points(a.geom), func.ST_StartPoint(b.geom))), func.ST_AsText( func.ST_ClosestPoint(func.ST_Points(a.geom), func.ST_EndPoint(b.geom))), func.ST_Distance(func.ST_StartPoint(b.geom), a.geom), func.ST_Distance(func.ST_EndPoint(b.geom), a.geom), func.ST_Distance(a.geom, b.geom)).filter( and_(a.shape_id == shape_id, func.ST_DWithin(a.geom, b.geom, 0.001))).order_by(a.id) """ , func.ST_ClosestPoint(func.ST_Points(a.geom), func.ST_StartPoint(b.geom)) , func.ST_ClosestPoint(func.ST_Points(a.geom), func.ST_EndPoint(b.geom)) , func.ST_ClosestPoint(func.ST_Points(b.geom), func.ST_StartPoint(a.geom)) , func.ST_ClosestPoint(func.ST_Points(b.geom), func.ST_EndPoint(a.geom)) , func.ST_Contains(func.ST_Buffer(a.geom, 0.00001), b.geom) , func.ST_Contains(func.ST_Buffer(a.geom, 0.0001), b.geom) , func.ST_Contains(func.ST_Buffer(a.geom, 0.001), b.geom) """ qsegs = self.group_results(rez) return qsegs
def prepare_merge(self): # Remove this when https://github.com/brazil-data-cube/stac.py/issues/10 is fixed. _ = stac_cli.catalog for tileid in self.mosaics: if len(self.mosaics) != 1: self.params['tileid'] = tileid continue bbox_result = db.session.query( Tile.id, func.ST_AsText( func.ST_BoundingDiagonal(func.ST_Force2D( Tile.geom_wgs84)))).filter(Tile.id == tileid).first() bbox = bbox_result[1][bbox_result[1].find('(') + 1:bbox_result[0].find(')')] bbox = bbox.replace(' ', ',') for periodkey in self.mosaics[tileid]['periods']: start = self.mosaics[tileid]['periods'][periodkey]['start'] end = self.mosaics[tileid]['periods'][periodkey]['end'] # Search all images self.mosaics[tileid]['periods'][periodkey][ 'scenes'] = self.search_images(bbox, start, end)
def get_bbox(tile_id: str) -> str: """Retrieve the bounding box representation as string.""" bbox_result = db.session.query( Tile.id, func.ST_AsText( func.ST_BoundingDiagonal(func.ST_Force2D( Tile.geom_wgs84)))).filter(Tile.id == tile_id).first() bbox = bbox_result[1][bbox_result[1].find('(') + 1:bbox_result[0].find(')')] bbox = bbox.replace(' ', ',') return bbox
def get_bbox(tile_id: str, grs: GridRefSys) -> str: """Retrieve the bounding box representation as string.""" geom_table = grs.geom_table bbox_result = db.session.query( geom_table.c.tile, func.ST_AsText(func.ST_BoundingDiagonal(func.ST_Transform(geom_table.c.geom, 4326))) ).filter( geom_table.c.tile == tile_id ).first() bbox = bbox_result[1][bbox_result[1].find('(') + 1:bbox_result[0].find(')')] bbox = bbox.replace(' ', ',') return bbox
def create_tiles(self, tiles: List[str], collection: Collection): """Create Collection tiles on database. Args: tiles - List of tiles in same GRS schema of collection collection - Collection object """ tiles_by_grs = db.session() \ .query(Tile, func.ST_AsText(func.ST_BoundingDiagonal(Tile.geom_wgs84))) \ .filter( Tile.grs_schema_id == collection.grs_schema_id, Tile.id.in_(tiles) ).all() collection_tiles = [] tiles = list(set(tiles)) tiles_infos = {} datacube = "_".join(collection.id.split('_')[:-1]) with db.session.begin_nested(): for tile in tiles: # verify tile exists tile_info = list( filter(lambda t: t[0].id == tile, tiles_by_grs)) if not tile_info: raise RuntimeError( 'Tile ({}) not found in GRS ({})'.format( tile, collection.grs_schema_id)) tiles_infos[tile] = tile_info[0] for function in ['WARPED', 'STK', 'MED']: collection_tile = CollectionTile.query().filter( CollectionTile.collection_id == '{}_{}'.format( datacube, function), CollectionTile.grs_schema_id == collection.grs_schema_id, CollectionTile.tile_id == tile).first() if not collection_tile: CollectionTile(collection_id='{}_{}'.format( datacube, function), grs_schema_id=collection.grs_schema_id, tile_id=tile).save(commit=False) db.session.commit()
def index(self): if request.args.get('bounds') is None: return Response(json.dumps([]), mimetype='application/json') bounds_parts = request.args.get("bounds").split(',') zoom = int(request.args.get("zoom") or 1) powerlines = [] if int(zoom) < 12: if int(zoom) < 8: # min_lenth is a multiplicator to reduce the number of shown powerlines based on their length and # zoom level min_length = 15000 else: min_length = 10000 powerlines = Powerline.query.filter( func.ST_Intersects( func.ST_MakeEnvelope(bounds_parts[1], bounds_parts[0], bounds_parts[3], bounds_parts[2]), Powerline.geom)).filter( func.ST_Length( func.ST_GeographyFromText( func.ST_AsText(Powerline.geom))) > min_length * (10 - zoom)).all() else: powerlines = Powerline.query.filter( func.ST_Intersects( func.ST_MakeEnvelope(bounds_parts[1], bounds_parts[0], bounds_parts[3], bounds_parts[2]), Powerline.geom)).all() powerlines = list( map(lambda powerline: powerline.serialize(), powerlines)) return Response(json.dumps(powerlines), mimetype='application/json')
def orchestrate(datacube, cube_infos, tiles, start_date, end_date): # create collection_tiles tiles_by_grs = db.session() \ .query(Tile, func.ST_AsText(func.ST_BoundingDiagonal(Tile.geom_wgs84))) \ .filter( Tile.grs_schema_id == cube_infos.grs_schema_id, Tile.id.in_(tiles) ).all() collection_tiles = [] tiles = list(set(tiles)) tiles_infos = {} for tile in tiles: # verify tile exists tile_info = list(filter(lambda t: t[0].id == tile, tiles_by_grs)) if not tile_info: return 'tile ({}) not found in GRS ({})'.format(tile, cube_infos.grs_schema_id), 404 tiles_infos[tile] = tile_info[0] for function in ['IDENTITY', 'STK', 'MED']: cube_id = get_cube_id(datacube, function) collection_tile = CollectionTile.query().filter( CollectionTile.collection_id == cube_id, CollectionTile.grs_schema_id == cube_infos.grs_schema_id, CollectionTile.tile_id == tile ).first() if not collection_tile: collection_tiles.append(CollectionTile( collection_id=cube_id, grs_schema_id=cube_infos.grs_schema_id, tile_id=tile )) BaseModel.save_all(collection_tiles) # get cube start_date if exists collections_items = CollectionItem.query().filter( CollectionItem.collection_id == cube_infos.id, CollectionItem.grs_schema_id == cube_infos.grs_schema_id ).order_by(CollectionItem.composite_start).all() cube_start_date = start_date if list(filter(lambda c_i: c_i.tile_id == tile, collections_items)): cube_start_date = collections_items[0].composite_start # get/mount timeline temporal_schema = cube_infos.temporal_composition_schema.temporal_schema step = cube_infos.temporal_composition_schema.temporal_composite_t timeline = decode_periods(temporal_schema.upper(), cube_start_date, end_date, int(step)) # create collection items (old model => mosaic) items_id = [] items = {} for datekey in sorted(timeline): requestedperiod = timeline[datekey] for periodkey in requestedperiod: (p_basedate, p_startdate, p_enddate) = periodkey.split('_') if start_date is not None and p_startdate < start_date : continue if end_date is not None and p_enddate > end_date : continue for tile in tiles: bbox = tiles_infos[tile][1].replace('LINESTRING(', '') \ .replace('LINESTRING Z (', '') \ .replace(')', '') \ .replace(' ', ',') \ .split(',') if len(bbox) != 4: del bbox[2] del bbox[-1] items[tile] = items.get(tile, {}) items[tile]['bbox'] = ','.join(bbox) items[tile]['xmin'] = tiles_infos[tile][0].min_x items[tile]['ymax'] = tiles_infos[tile][0].max_y items[tile]['periods'] = items[tile].get('periods', {}) item_id = '{}_{}_{}'.format(cube_infos.id, tile, p_basedate) if item_id not in items_id: items_id.append(item_id) if not list(filter(lambda c_i: c_i.id == item_id, collections_items)): items[tile]['periods'][periodkey] = { 'collection': cube_infos.id, 'grs_schema_id': cube_infos.grs_schema_id, 'tile_id': tile, 'item_date': p_basedate, 'id': item_id, 'composite_start': p_startdate, 'composite_end': p_enddate, 'dirname': '{}/{}/'.format(get_cube_id(datacube), tile) } return items