freifunkh / osm-borders

Retrieves polygons of administrative OpenStreetMap borders using osmapi and outputs as JSON
The Unlicense
1 stars 0 forks source link

beware of duplicate code #1

Closed AiyionPrime closed 3 years ago

AiyionPrime commented 3 years ago

Hey, @moridius implemented districtsTk a while ago. It's python based, tested, as well as documented.

Though it does only reflect the administrative regions of hanover, it might be, or at least be a big part of what you want to achieve here.

CodeFetch commented 3 years ago

@moridius How did you retrieve the polygon data?

@AiyionPrime I do not want to fiddle manually with such data and I don't want other Freifunkers to do it either. Therefore I decided to write a script.

CodeFetch commented 3 years ago

My script uses the OSM API to gather the hierarchy of areas. Then it loads the paths of the borders, joins them to one big path and then gets the coordinates for the nodes among the path. So I do not need to do anything manually. I remember moridius said that he had problems with gaps or something. I think he didn't use the outer lines. The outer lines must per definition have common nodes and from what I've seen the OSM data is correct.

AiyionPrime commented 3 years ago

@moridius How did you retrieve the polygon data?

Moridius fetched the data from the officials, which supplied him with a valid geojson of hanovers districts. The file is available on hanovers website.

@AiyionPrime I do not want to fiddle manually with such data and I don't want other Freifunkers to do it either. Therefore I decided to write a script.

That was Moridius' approach as well. Please be aware, that you are about to put a lot of effort in a project that's aready done for hanover and every other town, that has a geojson.

So I do not need to do anything manually.

I'm still sure you don't need to do anything, as the whole project is already implemented. Please test, whether districtsTk suits your needs, even if the data provider is 'only' hanover and not OSM. And if it really doesn't, examine how you'd extend it.

You are about to reach the next level of nih.

CodeFetch commented 3 years ago

@AiyionPrime I've seen the districts repository. What do you mean with districtsTk? Tkinter? I haven't seen a GUI. And I have no data for the Umland, but OSM data... What I write is a simple tool to get polygons of borders of administrative districts from OSM. As far as I know it's something totally different.

AiyionPrime commented 3 years ago

This is districtsTk on the python package index You can either download a released tarball from there, or have a look at development at the districtsTk.git repo on git@ns1.fnorden.net.

'Tk' stood for toolkit iirc.

What I write is a simple tool to get polygons of borders of administrative districts from OSM.

And what is already written is a simple tool to get polygons of borders of administrative districts from the citys official geojson.

As far as I know it's something totally different.

If you think so. But I suppose this is getting ridiculous, unless you have a look at the actual codebase. There are already several functions that efficiently implement lookup-operations, e.g. whether a dot is in or out a n-sided polygon.

And even if Schwarmstedt did not have a geo-json just yet, it's something you could ask their IT for, as we already have pretty decent contacts in that direction.

I am still sure there is no need tom implement this a second time. There are more interesting and even unsolved problems you could spent your time on.

CodeFetch commented 3 years ago

@AiyionPrime I need the polygons of the region Hanover, not the city. OSM has every kind of border one can imagine and there is a simple tool missing for exporting the polygons. districtsTK is not related. There is an online tool for getting OSM boundary polygons, but it seems nobody has written an open source script for this, yet.

CodeFetch commented 3 years ago

@AiyionPrime It's like "I just want a polygon from OSM, why do I need to use this crappy, not-open-source tool?" I spend an hour or two for writing this, which saves 100s of hours of people who can't... It's just frustration... If moridius tool could do this, I'd be happy, but it relies on data and there is no data other than OSM for the Region Hannover. So I can't do anything with moridius tool without my script...

CodeFetch commented 3 years ago

I just want something that works, nothing big:

from osmapi import OsmApi
from json import dumps, loads
import time

LANGUAGE = "de"

def slow(ret):
    time.sleep(0.15)
    return ret

def get_name(relation):
    if ('name:' + LANGUAGE) in relation['tag']:
        return relation['tag']['name:' + LANGUAGE]

    return relation['tag']['name']

def add_path(path, fullpath, upaths):
    added = False
# TODO reverse paths
    if path[0] in fullpath:
        print("found begin")
        pos = border.index(path[0])
        border[pos+1:pos+1] = path[1:]
        added = True
    elif path[-1] in fullpath:
        print("found end")
        pos = fullpath.index(path[-1])
        fullpath[pos:pos] = path[:-1]
        added = True
    else:
        upaths.append(path)

    # We need to check recursively if the unknown paths fits
    if added:
        new_upaths = upaths
        for p in upaths:
            if len(p) and p in new_upaths:
                ret, paths, new_upaths = add_path(p, fullpath, new_upaths)

    return added, fullpath, upaths

def __get_area(relation, recursionlevel, notlastlevel):
    area = {
        'name': get_name(relation),
        'boundary': relation['tag']['boundary'],
        'admin_level': relation['tag']['admin_level']
    }

    print("--" * (recursionlevel - notlastlevel), area['name'], "Relation ID:", relation['id'])
    subareas = []
    polypath = []
    borderways = []
    for member in relation['member']:        
        if notlastlevel and "subarea" == member['role'] and "relation" == member['type']:
            subareas.append(__get_area(api.RelationGet(member['ref']), recursionlevel, notlastlevel - 1))
        elif "outer" == member['role'] and "way" == member['type']:
            borderways.append(member['ref'])

    if len(subareas):
        print(len(subareas))
        area['subareas'] = subareas

    if len(polypath):
        area['subareas'] = subareas

    if len(borderways):
        area['borderways'] = borderways

    return area

def get_area(relation, recursionlevel = 1):
    return __get_area(relation, recursionlevel, recursionlevel)

api = OsmApi()
# Region Hannover 62764
bways = get_area(api.RelationGet(slow(11623875)), 5)['borderways']

for way in bways:
    w = api.WayGet(slow(way))
    path = w['nd']
    print(path)

#print(get_area(api.RelationGet(slow(11623875)), 5))

'''
For borderways:
        border = []
        unknownpaths = []
            way = api.WayGet(slow(member['ref']))
            path = way['nd']
            if way['visible'] and len(path):
                ret, border, unknownpaths = add_path(path, border, unknownpaths)

    if len(border) and border[0] == border[-1]:
        print("Complete path")
        for nodes in border:
            n = api.NodeGet(slow(node))
            polypath.append((n['lat'], n['lon']))
'''
AiyionPrime commented 3 years ago

There are several opensource tools, that do what you want, including overpass turbo using the overpass api or even simpler the completely enduser friendly https://geojson.io -.-'

Your conclusion is, 'there's someone involved with osm, thats written exactly what I want. But I can write it too, and hope others will find my rather untested and undocumented piece of python more useful than that neat web-ui the other one has written'.

It's like "I just want a polygon from OSM, why do I need to use this crappy, not-open-source tool?"

It is neither 'crappy', nor 'not-open-source'.

  1. metager.de
  2. enter 'http://polygons.openstreetmap.fr/ sourcecode'
  3. open the literally first search result https://github.com/jocelynj/osm-polygons-generation

Like really, this is getting to ridiculous. Lets talk about this later today.

AiyionPrime commented 3 years ago

@moridius Maybe we could expand districtsTk with an option to take relation ids...

CodeFetch commented 3 years ago

@AiyionPrime So how do I use this? I don't know...

Edit: I think it expects you to have a copy of OSM. I just want to use the OSM API...