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)
Example #3
0
            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">
Example #4
0
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)