def _adapt_feature_geometry(feature: geojson.Feature) -> geojson.Feature: """ Adapts the feature geometry to be used as a shapely geometry :param feature: geojson.feature to be adapted :return: feature with geometry adapted """ if isinstance( feature.geometry, (geojson.geometry.Polygon, geojson.geometry.MultiPolygon)): # adapt the geometry for use as a shapely geometry http://toblerity.org/shapely/manual.html#shapely.geometry.asShape feature.geometry = shapely.geometry.asShape(feature.geometry) return feature else: return None
def build_municipality_list(department, vectorized, given_insee=None, force_download=None, umap=False): """Build municipality list """ department = department.zfill(2) txt_content = '' department_stats = [] if args.database is not None: (host, port, user, password, database) = args.database.split(":") connection = psycopg2.connect(host=host, port=port, user=user, password=password, database=database) cursor = connection.cursor() counter = 0 relations = get_municipality_relations(department, given_insee, force_download == "all") for relation in relations: counter += 1 tags = relation.get('tags') insee = tags.get('ref:INSEE') name = tags.get('name') postcode = tags.get('addr:postcode') if insee in vectorized: vector = 'vector' try: relation_src = count_sources('relation', insee, force_download in ["all", "relations"]) building_src = count_sources('building', insee, force_download in ["all", "buildings"]) except overpass.errors.ServerRuntimeError as e: log.error("Fail to query overpass for {}. Consider reporting the bug: {}. Skipping".format(insee, e)) continue dates = sorted(building_src.items(), key=lambda t: t[1], reverse=True) date = dates[0][0] if len(dates) else None color = color_by_date(date) description = 'Building:\n{}\nRelation:\n{}'.format(stats_to_txt(building_src), stats_to_txt(relation_src)) else: date = 'raster' vector = 'raster' color = 'black' description = 'Raster' municipality_border = Feature( properties={ 'insee': insee, 'name': name, 'postcode': postcode, 'description': description, }, ) if umap: municipality_border.properties['_storage_options'] = { 'color': color, 'weight': '1', 'fillOpacity': '0.5', 'labelHover': True, } else: municipality_border.properties['color'] = color municipality_border.geometry = get_geometry_for(relation) if args.database is not None: log.debug("Updating database") try: req = (""" INSERT INTO color_city VALUES ('{}', '{}', '{}', now()) ON CONFLICT (insee) DO UPDATE SET color = excluded.color, department = excluded.department """.format(insee, color, department)) # only update date if we did not use cache files for buildings if force_download in ["all", "buildings"]: req += ", last_update = excluded.last_update" cursor.execute(req) except Exception as e: log.warning("Cannot write in database: " + str(e)) pass log.info("{:.2f}% Treated {} - {} (last import: {})".format(100 * counter / len(relations), insee, name, date)) department_stats.append(municipality_border) txt_content += '{},{},{},{}\n'.format(insee, name, postcode, vector) # commit database changes only after the whole loop to 1. speed up 2. avoid # semi-updated database in case of error in the middle connection.commit() # write geojson log.debug('Write {}.geojson'.format(department)) geojson_path = path.join(STATS_PATH, '{}.geojson'.format(department)) if path.exists(geojson_path) and given_insee: department_geojson = geojson.loads(open(geojson_path).read()) found = False for municipality in department_geojson["features"]: if municipality["properties"]["insee"] == given_insee: found = True index = department_geojson["features"].index(municipality) department_geojson["features"] = department_geojson["features"][:index] + department_stats + department_geojson["features"][index + 1:] break if not found: department_geojson["features"] += department_stats else: department_geojson = FeatureCollection(department_stats) with open(geojson_path, 'w') as fd: # we should not indent the GeoJSON because it drastically reduce the final size # (x10 or so) fd.write(geojson.dumps(department_geojson, indent=None, sort_keys=True)) # write txt log.debug('Write {}-municipality.txt'.format(department)) txt_path = path.join(STATS_PATH, '{}-municipality.txt'.format(department)) with open(txt_path, 'w') as fd: fd.write(txt_content)
f.properties.update({ 'fillOpacity': 0.0, 'opacity': 0.0, 'color': '#ffffff' }) elif class_ in ['Luftsport']: if to_ < 2000: f.properties.update({'fillColor': '#c0c040', 'color': '#c0c040'}) else: f.properties.update({'fillColor': '#40c040', 'color': '#40c040'}) else: logger.debug("Missing color scheme for: %s, %s", class_, from_) if geom[0] != geom[-1]: geom.append(geom[0]) if from_ < 4200: f.geometry = Polygon([geom]) fc.append(f) result = FeatureCollection(fc) if len(sys.argv) > 1: print 'http://geojson.io/#data=data:application/json,' + urllib.quote( str(result)) open("result/luftrom.geojson", "w", "utf-8").write(str(result)) # OpenAIP output logger.info("Converting to OpenAIP") out = open("result/luftrom.openaip", "w", "utf-8") out.write("""<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <OPENAIP VERSION="367810a0f94887bf79cd9432d2a01142b0426795" DATAFORMAT="1.1">
def build_municipality_list(department): """Build municipality list """ api = overpass.API() response = api.Get( '''[out:json]; relation [boundary="administrative"] [admin_level=8] ["ref:INSEE"~"{}..."]; out geom qt;'''.format(department), responseformat="json", build=False, ) features = [] txt_content = '' for relation in response.get('elements'): outer_ways = [] for member in relation.get('members'): if member.get('role') == 'outer': way = [] for point in member.get('geometry'): way.append((point.get('lon'), point.get('lat'))) outer_ways.append(way) tags = relation.get('tags') insee = tags.get('ref:INSEE') name = tags.get('name') postcode = tags.get('addr:postcode') municipality_border = Feature(properties={ 'insee': insee, 'name': name, 'postcode': postcode, '_storage_options': { 'color': color_for_insee(department, insee), 'weight': '1', 'fillOpacity': '0.5', }, }, ) border = lines_to_polygon(outer_ways) if not border: logging.warning('{} does not have borders'.format(name)) else: municipality_border.geometry = Polygon([border]) features.append(municipality_border) txt_content += '{},{},{}\n'.format(insee, name, postcode) # write municipality geojson muni_geojson_path = path.join(BORDER_PATH, '{}.geojson'.format(insee)) with open(muni_geojson_path, 'w') as fd: fd.write(geojson.dumps(municipality_border)) # write department geojson dep_geojson_path = path.join(STATS_PATH, '{}.geojson'.format(department)) with open(dep_geojson_path, 'w') as fd: fd.write(geojson.dumps(FeatureCollection(features))) # write txt txt_path = path.join(STATS_PATH, '{}-municipality.txt'.format(department)) with open(txt_path, 'w') as fd: fd.write(txt_content)