GIS analysis and application automatic generation of regional road network based on Gaud API

Author : xuzhiping   2022-12-14 14:06:45 Browse: 1265

Abstract: Principle introduction Gaode Map provides an API interface for path planning. By outputting parameters such as starting and endin...

Principle introduction

Gaode Map provides an API interface for path planning. By outputting parameters such as starting and ending points, it can output the travel paths of different travel modes such as walking, public transportation, and driving. When there are enough starting and ending points, the road network can be generated by merging the planned travel paths. Therefore, the question includes several parts:

  • How to generate enough starting and ending points automatically
  • Based on how to get the travel path from the starting and ending points, and combine the travel paths from different starting and ending points
  • Generate regional road network

Automatic generation of navigation start and end points

The search POI API interface provided by Gaud Map is used to extract the feature points within the specified area, and the feature points are regarded as the starting and ending coordinates of navigation. The specific implementation code is as follows:

import requests
import re
import json

import pandas as pd

def obtain_areapoilnglat(polygonlnglat,key,keywordslist=['School ',' Bank | ATM ',' Residential ',' McDonald's', 'KFC', 'Gas Station', 'Parking Lot', 'Hospital', 'Shopping Mall', 'Supermarket', 'Company', 'Hotel', 'Bus Station | Metro Station']:
    #The key is the "Web Service API" key of Godmap, and you need to apply for it yourself
    df_areapoi=pd.DataFrame()
    for keywords in keywordslist:  
        #print(keywords)
        pagenumber=1
        length=20
        while length>=20:
            #print(pagenumber)
            df_temp=poi(key,polygonlnglat,keywords,pagenumber)
            pagenumber=pagenumber+1
            length=len(df_temp)
            df_areapoi=df_areapoi.append(df_temp,ignore_index=True)
    return df_areapoi


def obtain_pdfromdicts(dicts):
    df_areapoi=pd.DataFrame()
    namelist=[address['name'] for address in dicts['pois']]
    lnglist=[float(address['location'].split(",")[0]) for address in dicts['pois']]
    latlist=[float(address['location'].split(",")[1]) for address in dicts['pois']]
    df_areapoi['name']=namelist
    df_areapoi['lng']=lnglist
    df_areapoi['lat']=latlist
    return df_areapoi

def poi(key:str,polygonlnglat:str,keywords:str,pagenumber:int)-> dict:
    parameters = {
        'key':key,
        'polygon':polygonlnglat,
        #'city':city,
        'keywords':keywords,
        'offset':20,
        'page':pagenumber,
        'output':'json'
    }
    r = requests.get('https://restapi.amap.com/v3/place/polygon?parameters',params = parameters)
    data = r.json()
    df_temp=obtain_pdfromdicts(data)
    #print(df_temp)
    return df_temp

Travel route extraction

The driving path planning results in json format can be obtained by inputting the parameters such as departure place, destination, route location, driving strategy and so on through the driving path planning API interface of Gaode Map:

The path planning result polyline is saved in the data frame format according to the mode of the minimum link unit (the minimum link has only two nodes: the starting point and the ending point). The sample data of the data frame result is as follows:

Travel route extraction

At the same time, the travel routes obtained from different starting and ending points are combined. When the designated area is large, the number of POI feature points extracted within the designated area will increase exponentially, and the number of navigation start and end points formed by pairwise combination of POI points will also increase exponentially. Considering the limitation of API interface calls and other factors, on the one hand, it is necessary to cluster POI points in blocks to reduce the number of navigation start and end points formed by pairwise combination of POI points. On the other hand, a maximum of 16 path points can be input in one call of the driving path planning API interface, which can make full use of this input parameter. In order to give readers space to think for themselves, this paper only gives how to use the path point parameter model to obtain road network data. Specifically, how to cluster POI points in blocks can be realized by the readers themselves.

The specific implementation code is as follows:

import numpy as np
def obtain_navigate(origin,destination,key,waypoints=[],key,strategy=0):
    #The navigation path is generated based on the five parameters of starting point, destination, Gaud map API key, route point and navigation strategy
    url="https://restapi.amap.com/v3/direction/driving?"
    url=url+"origin="+str(origin[0])+","+str(origin[1])
    url=url+"&destination="+str(destination[0])+","+str(destination[1])
    url=url+"&extensions=base"
    url=url+"&strategy="+str(strategy)+'&output=JSON'
    if len(waypoints)>1:
        url=url+"&waypoints="+str(waypoints[0][0])+","+str(waypoints[0][1])
        for waypoint in waypoints[1:]:
            url=url+";"+str(waypoint[0])+","+str(waypoint[1]) 
    url=url+"&output=xml&key="+key
    #print(url)
    data= requests.get(url)
    dicts=json.loads(data.text)
    # pattern= re.compile(r'<step>(.*)</assistant_action>',re.M) 
    # steps=pattern.findall(data.text)
    polyline_result=[]
    t_sum=0
    d_sum=0
    waypoints_travel_list=[]
    twowaypoints_navigate_result=[]
    try:
        for polyline in  dicts['route']['paths'][0]['steps']:
            navigate_result_polyline=[list(map(float,point.split(","))) for point in polyline['polyline'].split(";")]
            #polyline_result=polyline_result+[list(map(float,point.split(","))) for point in polyline['polyline'].split(";")][1:-1]   ###The first and last navigation paths between two points are removed
            #print(polyline_result)
            d_sum=d_sum+float(polyline['distance'])
            t_sum=t_sum+float(polyline['duration'])
            assistant_action=polyline['assistant_action']
            twowaypoints_navigate_result=twowaypoints_navigate_result+navigate_result_polyline
            if assistant_action=="Arrive at the destination" or assistant_action=="terminus ad quem":
                twowaypoints_navigate_result=twowaypoints_navigate_result[1:-1]
                polyline_result=polyline_result+twowaypoints_navigate_result
                speed_average=d_sum/t_sum
                waypoints_travel_list.append([d_sum,t_sum,speed_average])
                t_sum=0
                d_sum=0
                twowaypoints_navigate_result=[]
        t=[polyline_result[i] for i in range(1,len(polyline_result)) if polyline_result[i]!=polyline_result[i-1]]
        polyline_result=[polyline_result[0]]+t
        new=pd.DataFrame(polyline_result,columns=['lng','lat']) 
        new1=new.copy()
        new1=new1.drop(new1.index[0])
        new1.index=range(len(new1))
        new1.columns=['nextlng','nextlat']
        new2=new.copy()
        new2=new2.drop(new2.index[-1])
        new2.index=range(len(new2))
        df_polyline_result=pd.concat([new1,new2],axis=1)
        return df_polyline_result
    except:
        return pd.DataFrame()

def obtain_all_polyline_result(df_areapoi,waypointsmaxnumber=18):
    #Combine the obtained poi point information to generate road network data
    df_polyline_result_all=pd.DataFrame()
    n=int(np.floor(len(df_areapoi)/waypointsmaxnumber))
    for interval in range(1,n):
        for i in range(0,int(np.floor(n/interval))):
            for j in range(0,interval):   
                print(count)
                count=count+1
                startid=i*waypointsmaxnumber*interval+j
                endid=(i+1)*waypointsmaxnumber*interval+j    
                kk=list(range(startid,endid,interval))
                startid=kk[0]
                endid=kk[-1]
                origin=[df_areapoi.iloc[startid]['lng'],df_areapoi.iloc[startid]['lat']]
                destination=[df_areapoi.iloc[endid]['lng'],df_areapoi.iloc[endid]['lat']]
                waypoints= [[df_areapoi.loc[xx,'lng'],df_areapoi.loc[xx,'lat']] for xx in df_areapoi.iloc[kk].index]
                df_polyline_result=obtain_navigate(origin,destination,waypoints) 
                df_polyline_result_all=df_polyline_result_all.append(df_polyline_result,ignore_index=True)
    df_polyline_result_all=df_polyline_result_all.drop_duplicates()
    return df_polyline_result_all

Regional road network generation

This part is mainly about writing the result data generated in the third step to generate the road network data in geojson format.

import time
import requests
import re
import json
outputfilename='xxx.geojson'
key="xxxxxx"
polygonlnglat='120.22084,30.2634|120.292021,30.130141'
df_areapoi=obtain_areapoilnglat(polygonlnglat,key)
df_polyline_result_all=obtain_all_polyline_result(df_areapoi,waypointsmaxnumber=18)
ODlnglat_navigate_obtainnetwork(df_polyline_result_all,outputfilename)
fp.close()


def pd_propertyresult_2geojson(pd_propertyresult,geotype,outputfilename):
    #According to the obtained road network result data dataframe format, generate the road network in geojson format
    #geotype='Point' MultiLineString  LineString   Three forms
    fp = open(outputfilename,"w+")
    #Write at the beginning of the file
    st="""{
    "type": "FeatureCollection",
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
    "features": ["""
    fp.write(st+"\n")
    stable_str1="""{"type": "Feature", "properties": {"""
    stable_str2= """}, "geometry": { "type":\""""+geotype+"""\", "coordinates": """

    #del str
    for i in range(0,len(pd_propertyresult.index)):
        #print(i)
        geo_property=""" "id" """ +":"+"""\""""+str(i)+"""\""""+", "
        geo_property=geo_property[:-1]
        lnglat=[[pd_propertyresult.iloc[i]['lng'],pd_propertyresult.iloc[i]['lat']],[pd_propertyresult.iloc[i]['nextlng'],pd_propertyresult.iloc[i]['nextlat']]]
        if i==len(pd_propertyresult.index)-1:
            str1=stable_str1+geo_property+stable_str2+str(lnglat)+" } }"+"\n"
        else: 
            str1=stable_str1+geo_property+stable_str2+str(lnglat)+" } },"+"\n"
        fp.write(str1)
        #print("str1:",str1)
    #Write at the end of the file
    st2="""]
    }"""
    fp.write(st2+"\n")
    fp.close()

The resulting road network is as follows:

network

Label :
    Sign in for comments!
Comment list (0)

Powered by TorCMS (https://github.com/bukun/TorCMS).