Google maps 谷歌地图-如何获得建筑';从地址开始的多边形坐标是多少?

Google maps 谷歌地图-如何获得建筑';从地址开始的多边形坐标是多少?,google-maps,geolocation,geocoding,Google Maps,Geolocation,Geocoding,如何实施以下措施: 用户定义一个地址 用户定义颜色 服务在谷歌地图上搜索相应的建筑 服务使用颜色填充地图上找到的建筑 我知道如何: 1.查找地址的lat/long 2.画多边形 所以,为了完成这个任务,我需要从address中获取建筑物的多边形坐标。如何?谷歌地图API包含一个可能正是您所需要的。具体地说,是在几何体字段中返回的数据。我已经为此工作了几个小时,最近的一次是找到一个请求uri,该uri返回一个包含多边形的结果。我相信它通过editids参数指定了建筑(边界)。我们只需要一种从建筑物

如何实施以下措施:

  • 用户定义一个地址
  • 用户定义颜色
  • 服务在谷歌地图上搜索相应的建筑
  • 服务使用颜色填充地图上找到的建筑
  • 我知道如何:

    1.查找地址的lat/long

    2.画多边形


    所以,为了完成这个任务,我需要从address中获取建筑物的多边形坐标。如何?

    谷歌地图API包含一个可能正是您所需要的。具体地说,是在
    几何体
    字段中返回的数据。

    我已经为此工作了几个小时,最近的一次是找到一个请求uri,该uri返回一个包含多边形的结果。我相信它通过
    editids
    参数指定了建筑(边界)。我们只需要一种从建筑物(边界)获取当前editid的方法

    我的URI是:

    https://www.google.com/mapmaker?hl=en&gw=40&output=jsonp&ll=38.934911%2C-92.329359&spn=0.016288%2C0.056477&z=14&mpnum=0&vpid=1354239392511&editids=nAlkfrzSpBMuVg-hSJ&xauth=YOUR_XAUTH_HERE&geowiki_client=mapmaker&hl=en
    
    部分结果具有所需的功能:

    "polygon":[{"gnew":{"loop":[{"vertex":[{"lat_e7":389364691,"lng_e7":-923341133},{"lat_e7":389362067,"lng_e7":-923342783},{"lat_e7":389361075,"lng_e7":-923343356},{"lat_e7":389360594,"lng_e7":-923342477},
    
    (一)

    (2) 基于像素颜色(此处为0xF2EEE6)分割建筑物

    (3) 图像清理(例如)+获取多边形角点像素坐标的算法


    (4) 我对这个问题很感兴趣,并写了一个解决方案。请参阅。

    您可以使用谷歌地理编码API将地址转换为地理坐标

    https://maps.googleapis.com/maps/api/geocode/json?address=SOME_ADDRESS&key=YOUR_API_KEY
    
    然后,您可以使用Python和已设置样式的静态贴图在某个位置获取建筑物的多边形(以像素坐标表示):

    import numpy as np
    from requests.utils import quote
    from skimage.measure import find_contours, points_in_poly, approximate_polygon
    from skimage import io
    from skimage import color
    from threading import Thread
    
    center_latitude = None ##put latitude here 
    center_longitude = None ##put longitude here 
    mapZoom = str(20)
    midX = 300
    midY = 300
    # Styled google maps url showing only the buildings
    safeURL_Style = quote('feature:landscape.man_made|element:geometry.stroke|visibility:on|color:0xffffff|weight:1')
    urlBuildings = "http://maps.googleapis.com/maps/api/staticmap?center=" + str_Center + "&zoom=" + mapZoom + "&format=png32&sensor=false&size=" + str_Size + "&maptype=roadmap&style=visibility:off&style=" + safeURL_Style
    
    mainBuilding = None
    imgBuildings = io.imread(urlBuildings)
    gray_imgBuildings = color.rgb2gray(imgBuildings)
    # will create inverted binary image
    binary_imageBuildings = np.where(gray_imgBuildings > np.mean(gray_imgBuildings), 0.0, 1.0)
    contoursBuildings = find_contours(binary_imageBuildings, 0.1)
    
    for n, contourBuilding in enumerate(contoursBuildings):
        if (contourBuilding[0, 1] == contourBuilding[-1, 1]) and (contourBuilding[0, 0] == contourBuilding[-1, 0]):
            # check if it is inside any other polygon, so this will remove any additional elements
            isInside = False
            skipPoly = False
            for othersPolygon in contoursBuildings:
                isInside = points_in_poly(contourBuilding, othersPolygon)
                if all(isInside):
                    skipPoly = True
                    break
    
            if skipPoly == False:
                center_inside = points_in_poly(np.array([[midX, midY]]), contourBuilding)
                if center_inside:
            # approximate will generalize the polygon
                    mainBuilding = approximate_polygon(contourBuilding, tolerance=2)
    
    print(mainBuilding)
    
    现在,您可以使用little JavaScript和Google Maps API将像素坐标转换为纬度和经度:

    function point2LatLng(point, map) {
            var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
            var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
            var scale = Math.pow(2, map.getZoom());
            var worldPoint = new google.maps.Point(point.x / scale + bottomLeft.x, point.y / scale + topRight.y);
            return map.getProjection().fromPointToLatLng(worldPoint);
    }
    
    var convertedPointsMain = [];
    
    for (var i = 0; i < pxlMainPolygons[p].length; i++) {
        var conv_point = {
            x: Math.round(pxlMainPolygons[p][i][1]),
            y: Math.round(pxlMainPolygons[p][i][0])
        }; 
        convertedPointsMain[i] = point2LatLng(conv_point, map);
    }
    
    console.log(convertedPointsMain);
    
    功能点2LATLNG(点,映射){
    var topRight=map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
    var bottomLeft=map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
    var scale=Math.pow(2,map.getZoom());
    var worldPoint=new google.maps.Point(Point.x/scale+bottomLeft.x,Point.y/scale+topRight.y);
    返回map.getProjection().fromPointToLatLng(worldPoint);
    }
    var convertedPointsMain=[];
    对于(var i=0;i
    我可以谦恭地建议您使用OpenStreetMaps来代替吗
    这要容易得多,因为这样你就可以使用
    但是,多边形可能与谷歌地图或州调查不匹配。
    如果你使用谷歌地图,后者也适用

    // https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL
    private static string GetOqlBuildingQuery(int distance, decimal latitude, decimal longitude)
    {
        System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo()
        {
            NumberGroupSeparator = "",
            NumberDecimalSeparator = ".",
            CurrencyGroupSeparator = "",
            CurrencyDecimalSeparator = ".",
            CurrencySymbol = ""
        };
    
        // [out: json];
        // way(around:25, 47.360867, 8.534703)["building"];
        // out ids geom meta;
    
        string oqlQuery = @"[out:json];
    way(around:" + distance.ToString(nfi) + ", "
    + latitude.ToString(nfi) + ", " + longitude.ToString(nfi)
    + @")[""building""];
    out ids geom;"; // ohne meta - ist minimal
    
        return oqlQuery;
    }
    
    
    
    
    public static System.Collections.Generic.List<Wgs84Point> GetWgs84PolygonPoints(int distance, decimal latitude, decimal longitude)
    {
        string[] overpass_services = new string[] {
            "http://overpass.osm.ch/api/interpreter",
            "http://overpass.openstreetmap.fr/api/interpreter",
            "http://overpass-api.de/api/interpreter",
            "http://overpass.osm.rambler.ru/cgi/interpreter",
            // "https://overpass.osm.vi-di.fr/api/interpreter", // offline...
        };
    
        // string url = "http://overpass.osm.ch/api/interpreter";
        // string url = "http://overpass-api.de/api/interpreter";
        string url = overpass_services[s_rnd.Next(0, overpass_services.Length)];
    
    
        System.Collections.Specialized.NameValueCollection reqparm = new System.Collections.Specialized.NameValueCollection();
        reqparm.Add("data", GetOqlBuildingQuery(distance, latitude, longitude));
    
        string resp = PostRequest(url, reqparm);
        // System.IO.File.WriteAllText(@"D:\username\Documents\visual studio 2017\Projects\TestPlotly\TestSpatial\testResponse.json", resp, System.Text.Encoding.UTF8);
        // System.Console.WriteLine(resp);
        // string resp = System.IO.File.ReadAllText(@"D:\username\Documents\visual studio 2017\Projects\TestPlotly\TestSpatial\testResponse.json", System.Text.Encoding.UTF8);
    
        System.Collections.Generic.List<Wgs84Point> ls = null;
    
        Overpass.Building.BuildingInfo ro = Overpass.Building.BuildingInfo.FromJson(resp);
    
        if (ro != null && ro.Elements != null && ro.Elements.Count > 0 && ro.Elements[0].Geometry != null)
        {
            ls = new System.Collections.Generic.List<Wgs84Point>();
    
            for (int i = 0; i < ro.Elements[0].Geometry.Count; ++i)
            {
                ls.Add(new Wgs84Point(ro.Elements[0].Geometry[i].Latitude, ro.Elements[0].Geometry[i].Longitude, i));
            } // Next i 
    
        } // End if (ro != null && ro.Elements != null && ro.Elements.Count > 0 && ro.Elements[0].Geometry != null) 
    
    
        return ls;
    } // End Function GetWgs84Points 
    
    //https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL
    私有静态字符串GetOqlBuildingQuery(整数距离、十进制纬度、十进制经度)
    {
    System.Globalization.NumberFormatInfo nfi=新的System.Globalization.NumberFormatInfo()
    {
    NumberGroupSeparator=“”,
    NumberDecimalSeparator=“.”,
    CurrencyGroupSeparator=“”,
    CurrencyDecimalSeparator=“.”,
    CurrencySymbol=“”
    };
    //[out:json];
    //路(约:2547.360867,8.534703)("建筑物");;
    //out-ids-geom-meta;
    字符串oqlQuery=@“[out:json];
    方式(大约:“+distance.ToString(nfi)+”,”
    +纬度.ToString(nfi)+“,”+经度.ToString(nfi)
    +@“[“建筑物”];
    out-ids geom;“;//ohne-meta-ist-minimal
    返回oqlQuery;
    }
    公共静态System.Collections.Generic.List GetWGS84多边形点(整数距离、十进制纬度、十进制经度)
    {
    字符串[]立交桥服务=新字符串[]{
    "http://overpass.osm.ch/api/interpreter",
    "http://overpass.openstreetmap.fr/api/interpreter",
    "http://overpass-api.de/api/interpreter",
    "http://overpass.osm.rambler.ru/cgi/interpreter",
    // "https://overpass.osm.vi-di.fr/api/interpreter“,//脱机。。。
    };
    //字符串url=”http://overpass.osm.ch/api/interpreter";
    //字符串url=”http://overpass-api.de/api/interpreter";
    字符串url=overpass\u services[s\u rnd.Next(0,overpass\u services.Length)];
    System.Collections.Specialized.NameValueCollection reqparm=新的System.Collections.Specialized.NameValueCollection();
    请求参数添加(“数据”,GetOqlBuildingQuery(距离、纬度、经度));
    字符串resp=PostRequest(url,reqparm);
    //System.IO.File.writealText(@“D:\username\Documents\visual studio 2017\Projects\TestPlotly\TestSpatial\testResponse.json”,resp,System.Text.Encoding.UTF8);
    //系统控制台写入线(resp);
    //string resp=System.IO.File.ReadAllText(@“D:\username\Documents\visualstudio 2017\Projects\TestPlotly\testspace\testResponse.json”,System.Text.Encoding.UTF8);
    System.Collections.Generic.List ls=null;
    Overpass.Building.BuildingInfo ro=Overpass.Building.BuildingInfo.FromJson(resp);
    如果(ro!=null&&ro.Elements!=null&&ro.Elements.Count>0&&ro.Elements[0]。几何体!=null)
    {
    ls=new System.Collections.Generic.List();
    对于(int i=0;i0&&ro.Elements[0]。几何体!=null)结束
    返回ls;
    }//结束函数GetWGS84点
    
    Raymond,谢谢分享!我还在寻找解决办法。如何生成这样的uri以及如何从响应中提取多边形数据?可能吗?