谷歌地图如何显示城市或区域轮廓

55
如何展示地点或区域的轮廓,就像以下网站所做的那样: [我输入一个区域,它会显示该区域的清晰边界。]

enter image description here

链接

我在官方地图文档中搜索了数小时,但没有找到这些网站如何显示区域边界的线索。也查看了一些旧问题并阅读了它不可能的答案。

6个回答

81

根据我的搜索,在目前的Maps API v3中,谷歌没有提供选项。自2008年以来,Google Maps API一直存在一个问题。 有一些早期的问题 - 在Google地图结果上添加“搜索区域”轮廓Google已开始用粉色突出显示搜索区域。这个功能是否在Google Maps API 3中可用? 您可能会发现一些更新的答案,但这不是一个功能。

您可以在地图上绘制形状 - 但是需要知道您区域的边界坐标。

现在,为了获取行政区域边界,您需要做一些工作:http://www.gadm.org/country(如果您很幸运并且那里提供足够的详细级别)。
在该网站上,您可以本地下载一个带有.kmz扩展名的文件(有许多格式可用)。解压缩它,您将获得一个包含大多数行政区域(城市、村庄)的.kml文件。
  <?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="x" id="x">
    <SimpleField name="ID_0" type="int"></SimpleField>
    <SimpleField name="ISO" type="string"></SimpleField>
    <SimpleField name="NAME_0" type="string"></SimpleField>
    <SimpleField name="ID_1" type="string"></SimpleField>
    <SimpleField name="NAME_1" type="string"></SimpleField>
    <SimpleField name="ID_2" type="string"></SimpleField>
    <SimpleField name="NAME_2" type="string"></SimpleField>
    <SimpleField name="TYPE_2" type="string"></SimpleField>
    <SimpleField name="ENGTYPE_2" type="string"></SimpleField>
    <SimpleField name="NL_NAME_2" type="string"></SimpleField>
    <SimpleField name="VARNAME_2" type="string"></SimpleField>
    <SimpleField name="Shape_Length" type="float"></SimpleField>
    <SimpleField name="Shape_Area" type="float"></SimpleField>
</Schema>
<Folder><name>x</name>
  <Placemark>
    <Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
    <ExtendedData><SchemaData schemaUrl="#x">
        <SimpleData name="ID_0">186</SimpleData>
        <SimpleData name="ISO">ROU</SimpleData>
        <SimpleData name="NAME_0">Romania</SimpleData>
        <SimpleData name="ID_1">1</SimpleData>
        <SimpleData name="NAME_1">Alba</SimpleData>
        <SimpleData name="ID_2">1</SimpleData>
        <SimpleData name="NAME_2">Abrud</SimpleData>
        <SimpleData name="TYPE_2">Comune</SimpleData>
        <SimpleData name="ENGTYPE_2">Commune</SimpleData>
        <SimpleData name="VARNAME_2">Oras Abrud</SimpleData>
        <SimpleData name="Shape_Length">0.2792904164402</SimpleData>
        <SimpleData name="Shape_Area">0.00302673357146115</SimpleData>
    </SchemaData></ExtendedData>
      <MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>23.117561340332031,46.269237518310547 23.108898162841797,46.265365600585937 23.107486724853629,46.264305114746207 23.104681015014762,46.260105133056641 23.101633071899471,46.250000000000114 23.100803375244254,46.249053955078239 23.097520828247184,46.246582031250114 23.0965576171875,46.245487213134822 23.095674514770508,46.244930267334098 23.092174530029354,46.243438720703182 23.088010787963924,46.240383148193473 23.083366394043082,46.238204956054801 23.075212478637809,46.234935760498047 23.071325302123967,46.239696502685547 23.070602416992131,46.241668701171875 23.069700241088924,46.242824554443416 23.068435668945369,46.243541717529354 23.066627502441406,46.244037628173771 23.064964294433651,46.246234893798885 23.062850952148437,46.247486114501953 23.0626220703125,46.248153686523438 23.062761306762752,46.250873565673942 23.061862945556697,46.255172729492301 23.061449050903434,46.256267547607422 23.05998420715332,46.258060455322322 23.057676315307674,46.259838104248161 23.055141448974666,46.262714385986442 23.053401947021484,46.264244079589901 23.049621582031193,46.266674041748161 23.043565750122013,46.268516540527457 23.041521072387695,46.269458770751953 23.034791946411076,46.270542144775334 23.027051925659293,46.27105712890625 23.025453567504826,46.271255493164063 23.022710800170898,46.272083282470703 23.020351409912053,46.271331787109432 23.018688201904297,46.270687103271598 23.015596389770508,46.270793914794922 23.014116287231502,46.271579742431697 23.009817123413143,46.275333404541016 23.006668090820426,46.277061462402401 23.004106521606445,46.279254913330135 23.001775741577205,46.282882690429688 23.005559921264648,46.283077239990348 23.009967803955135,46.28415679931652 23.014947891235465,46.286224365234489 23.019996643066463,46.28900146484375 23.024263381958121,46.292709350586051 23.027633666992301,46.295299530029411 23.028041839599609,46.295692443847656 23.032444000244197,46.294342041015625 23.03491401672369,46.293315887451229 23.044847488403434,46.290401458740234 23.047790527343807,46.28928375244152 23.053009033203239,46.288627624511719 23.057231903076229,46.288341522216797 23.064565658569393,46.287548065185547 23.070388793945426,46.286254882812614 23.075139999389592,46.284847259521428 23.075983047485465,46.284801483154411 23.085800170898494,46.28253173828125 23.098115921020451,46.280982971191406 23.099718093872127,46.280590057373104 23.105833053588981,46.278388977050838 23.112155914306641,46.274082183837947 23.116207122802791,46.270610809326172 23.117561340332031,46.269237518310547</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
  </Placemark>
</Folder>
</Document></kml>

从现在开始,当用户搜索一个城市/村庄时,您只需检索边界并在地图上绘制这些坐标周围的图形 - https://developers.google.com/maps/documentation/javascript/overlays#Polygons 希望这可以帮助您!祝好运! border on Google Map using the above coordinates 更新:我使用上述坐标制作了该城市的边界
                   var ctaLayer = new google.maps.KmlLayer({
                       url: 'https://www.dropbox.com/s/0grhlim3q4572jp/ROU_adm2%20-%20Copy.kml?dl=1'
  });
  ctaLayer.setMap(map);

我在Dropbox上放了一个小的kml文件,其中包含单个城市的边界。
请注意,这使用Google内置的KML系统,在此系统中,其服务器获取文件、计算视图并将其返回给您-它的用途有限,我使用它来向您展示边界的外观。在您的应用程序中,您应该能够从kml文件中解析坐标,将它们放入数组中(正如多边形文档所告诉您的那样- https://developers.google.com/maps/documentation/javascript/examples/polygon-arrays),并显示它们。
请注意,Google设置的边界http://www.google.com/maps与此数据获取到的边界将存在差异。
祝你好运! enter image description here

更新:http://pastebin.com/x2V1aarJhttp://pastebin.com/Gh55EDW5 这些是网站的JavaScript文件(它们已经被压缩,所以我使用了在线工具使它们可读)。如果您对我的解决方案不完全满意,请自由研究它们。

祝你好运!


非常感谢您关注和提供解决方案。我还调查了网站获取某个区域坐标的网络调用,并找到了以下API:https://regions.housing.com/api/v1/polygon/show/2dd0d8ff553613d1aa3f。现在我的疑问是:我怎么能够获取这些坐标并如何维护这些数据。 - Chanakya Vadla
是的!你说得对,我需要编写API来返回给定区域的坐标,这需要很多手动工作。希望在未来,谷歌能够尽快公开获取区域边界坐标的API。再次感谢! - Chanakya Vadla
如果这是应用程序的重要部分,实现起来并不难,现在你已经有了边界。你必须决定它是否足够重要以完成这项工作!祝你好运! - radu-matei
@ChanuSukarno 那是什么API?当我访问根目录时,我得到了404错误。 - Phil Andrews
1
@One-One,我刚刚重新下载了数据,成功了。请再试一次。如果你的位置仍然无法使用,请让我寻找其他数据来源。 - radu-matei
显示剩余7条评论

4
我正在寻找同样的答案,发现了解决方法,
解决方案是使用样式地图,通过下面的链接,您可以通过向导创建自定义样式并同时测试:Google地图样式向导 您可以在此处检查所有可用选项:这里 以下是我的示例代码,它创建州的边界,并隐藏所有道路及其标签。
    var styles = [
  {
    "featureType": "administrative.province",
    "elementType": "geometry.stroke",
    "stylers": [
      { "visibility": "on" },
      { "weight": 2.5 },
      { "color": "#24b0e2" }
    ]
  },{
    "featureType": "road",
    "elementType": "geometry",
    "stylers": [
      { "visibility": "off" }
    ]
  },{
    "featureType": "administrative.locality",
    "stylers": [
      { "visibility": "off" }
    ]
  },{
    "featureType": "road",
    "elementType": "labels",
    "stylers": [
      { "visibility": "off" }
    ]
  }
];

  var  geocoder = new google.maps.Geocoder();
   geocoder.geocode({
       'address': "rajasthan"
   }, (results, status)=> {
     var mapOpts = {
       mapTypeId: google.maps.MapTypeId.ROADMAP,
       scaleControl: true,
       scrollwheel: false,
       styles:styles,
       center: results[0].geometry.location,
       zoom:6
     }
     map = new google.maps.Map(document.getElementById("map"), mapOpts);
   });

1
使用样式不起任何作用。目前边框样式可用的仅有国家和省一级。地点、社区和土地面积等级不起作用。你可以随意更改,也不会有所不同。 - tiagosilva

1
我有一个解决方案,虽然不完美但对我很管用。使用谷歌的多边形示例,并使用 Google 地图上的固定点获取纬度和经度位置。

卡尔加里固定点

我使用了我所谓的“目视复制和粘贴”技巧,在屏幕上查看数字,然后将其写入代码中;-)

<style>
  #map {
    height: 500px;
  }
</style>
<script>

// This example creates a simple polygon representing the host city of the 
// Greatest Outdoor Show On Earth.

 function initMap() {
   var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 9,
      center: {lat: 51.039, lng: -114.204},
      mapTypeId: 'terrain'
    });

    // Define the LatLng coordinates for the polygon's path.
    var triangleCoords = [
      {lat: 51.183, lng: -114.234},
      {lat: 51.154, lng: -114.235},
      {lat: 51.156, lng: -114.261},
      {lat: 51.104, lng: -114.259},
      {lat: 51.106, lng: -114.261},
      {lat: 51.102, lng: -114.272},
      {lat: 51.081, lng: -114.271},
      {lat: 51.081, lng: -114.234},
      {lat: 51.009, lng: -114.236},
      {lat: 51.008, lng: -114.141},
      {lat: 50.995, lng: -114.142},
      {lat: 50.998, lng: -114.160},
      {lat: 50.984, lng: -114.163},
      {lat: 50.987, lng: -114.141},
      {lat: 50.979, lng: -114.141},
      {lat: 50.921, lng: -114.141},
      {lat: 50.921, lng: -114.210},
      {lat: 50.893, lng: -114.210},
      {lat: 50.892, lng: -114.140},
      {lat: 50.888, lng: -114.139},
      {lat: 50.878, lng: -114.094},
      {lat: 50.878, lng: -113.994},
      {lat: 50.840, lng: -113.954},
      {lat: 50.854, lng: -113.905},
      {lat: 50.922, lng: -113.906},
      {lat: 50.935, lng: -113.877},
      {lat: 50.943, lng: -113.877},
      {lat: 50.955, lng: -113.912},
      {lat: 51.183, lng: -113.910}
    ];

    // Construct the polygon.
    var bermudaTriangle = new google.maps.Polygon({
      paths: triangleCoords,
      strokeColor: '#FF0000',
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: '#FF0000',
      fillOpacity: 0.35
    });
    bermudaTriangle.setMap(map);
  }
</script>


<div id="map"></div>
<script async defer src="https://maps.googleapis.com/maps/api/jskey=YOUR_API_KEY&callback=initMap">
</script>

这会给你卡尔加里的大纲。我在这里附上了一张图片。

我们如何在Android谷歌地图屏幕上实现相同的功能? - hpAndro

1
我在这里发布这篇文章,以防对任何人有用。
根据@radu-matei的接受答案建议,我编写了一个基本的解析器,用于解析gadm.org KML文件 - 这些是已解压缩的KMZ文件。
<?php 
if(!is_dir('./coords')){
  mkdir('./coords');
}

$split_at_level = 'NAME_1';

$file = file_get_contents('gadm36_PHL_3.kml');
$parts = explode('</Placemark>', $file);
$data=[];
$last_NAME_1 = false;

foreach($parts as $i => $part){
  $lines = explode("\n", $part);
  $record=[];
  foreach($lines as $line){
    $line = trim($line);
    if(strpos($line,'SimpleData')!==false){
      $key = substr($line,18,6);
      $val = strip_tags($line);
      $record[$key] = $val;
    }
    
    if(strpos($line,'MultiGeometry')!==false){
      $line = strip_tags($line);
      $coords = explode(' ',$line);
      foreach($coords as $coord){
        $geo = explode(',',$coord);
        $record['outline'][] = ['lat'=>$geo[1],'lng'=>$geo[0]];
      }
    }
    
    // we have all the data we need and the geographic region has changed so dump the data and free up RAM.
    if(isset($record['outline']) && $last_NAME_1!=$record[$split_at_level] && !empty($data)){
      
      $output = [];
      foreach($data as $place){
        $output[$place['NAME_2']][$place['NAME_3']] = $place['outline'];
      }
      
      
      $filename = $record[$split_at_level].'.json';
      file_put_contents('./coords/'.$filename, json_encode($output, JSON_NUMERIC_CHECK));
      $last_NAME_1 = $record[$split_at_level];
      $data = [];
    }
    if(!$i && isset($record[$split_at_level])){ // set $last_NAME_1 on first iteration
      $last_NAME_1 = $record[$split_at_level];
    }
  }
  $data[] = $record;
  
}

https://github.com/andyg2/parse-gadm-kml/

PHP输出用作多边形地图 https://jsfiddle.net/andyg2/0t1gwnja/22/

function initMap() {
  // Create InfoWindow
  var infoWindow = new google.maps.InfoWindow;
  
  // Create Map
  var map = new google.maps.Map(document.getElementById("map"), {
      "center": {
        "lat": 17.4102405548096,
        "lng": 121.279747009277
      },
      "zoom": 10,
      "mapTypeId": "terrain"
    });

  // Initiate object to hold 
  var polyMapZones = {};
  var manicipalities = Object.keys(coords);

  // first loop for municipalities (cities)
  for (var i = 0; i <= manicipalities.length; i++) {
    
    // grab the municipality
    var manicipality = coords[manicipalities[i]];

    // grab the barangays
    var barangays = Object.keys(manicipality);

    // second loop for barangays (suburb)
    for (var ii = 0; ii <= barangays.length; ii++) {
      
      // Create a unique but arbitrary string for polyMapZones object key
      var mapKey = manicipalities[i] + ", " + barangays[ii];
      
      // Generate a polygon from coordinates
      polyMapZones[mapKey] = new google.maps.Polygon({
          paths: manicipality[barangays[ii]],
          strokeColor: "#FF0000",
          strokeOpacity: 0.8,
          strokeWeight: 2,
          fillColor: "#FF0000",
          fillOpacity: 0.25,
          content: mapKey
        });

      // Add polygon to map
      polyMapZones[mapKey].setMap(map);

      // Add click event listener to map
      polyMapZones[mapKey].addListener('click', showInfoWindow);
    }
  }
  
  // function to show the info window (onclick) popup.
  function showInfoWindow(event) {
    var vertices = this.getPath();
    infoWindow.setContent(this.content);
    infoWindow.setPosition(event.latLng);
    infoWindow.open(map);
  }
}


// Example output from PHP parser https://github.com/andyg2/parse-gadm-kml/ (shortened to a couple of locations for brevity)
var coords = {
  "Balbalan": {
    "Ababa-An": [{
        "lat": 17.5102405548096,
        "lng": 121.279747009277
      }, {
        "lat": 17.5029907226563,
        "lng": 121.278900146484
      }, {
        "lat": 17.505220413208,
        "lng": 121.253547668457
      }, {
        "lat": 17.5342903137207,
        "lng": 121.25919342041
      }, {
        "lat": 17.5313892364502,
        "lng": 121.282249450684
      }, {
        "lat": 17.5102405548096,
        "lng": 121.279747009277
      }
    ],
    "Balantoy": [{
        "lat": 17.48344039917,
        "lng": 121.235931396484
      }, {
        "lat": 17.4670391082764,
        "lng": 121.223297119141
      }, {
        "lat": 17.4686908721924,
        "lng": 121.222190856934
      }, {
        "lat": 17.4687004089355,
        "lng": 121.220672607422
      }, {
        "lat": 17.4693698883057,
        "lng": 121.219276428223
      }, {
        "lat": 17.4695892333985,
        "lng": 121.217170715332
      }, {
        "lat": 17.4749698638917,
        "lng": 121.20133972168
      }, {
        "lat": 17.4942092895508,
        "lng": 121.213180541992
      }, {
        "lat": 17.49467086792,
        "lng": 121.214233398438
      }, {
        "lat": 17.4955501556398,
        "lng": 121.215431213379
      }, {
        "lat": 17.4958305358887,
        "lng": 121.215713500977
      }, {
        "lat": 17.4962692260743,
        "lng": 121.216003417969
      }, {
        "lat": 17.497880935669,
        "lng": 121.216361999512
      }, {
        "lat": 17.4981803894044,
        "lng": 121.217292785645
      }, {
        "lat": 17.4991607666016,
        "lng": 121.217956542969
      }, {
        "lat": 17.499969482422,
        "lng": 121.218017578125
      }, {
        "lat": 17.500249862671,
        "lng": 121.218948364258
      }, {
        "lat": 17.5011196136475,
        "lng": 121.219749450684
      }, {
        "lat": 17.5018901824951,
        "lng": 121.220642089844
      }, {
        "lat": 17.5073890686035,
        "lng": 121.226982116699
      }, {
        "lat": 17.505220413208,
        "lng": 121.253547668457
      }, {
        "lat": 17.48344039917,
        "lng": 121.235931396484
      }
    ],
    "Balbalan Proper": [{
        "lat": 17.4271106719971,
        "lng": 121.159126281738
      }, {
        "lat": 17.4291801452637,
        "lng": 121.146751403809
      }, {
        "lat": 17.4823303222656,
        "lng": 121.177932739258
      }, {
        "lat": 17.4749698638917,
        "lng": 121.20133972168
      }, {
        "lat": 17.4695892333985,
        "lng": 121.217170715332
      }, {
        "lat": 17.4693698883057,
        "lng": 121.219276428223
      }, {
        "lat": 17.4687004089355,
        "lng": 121.220672607422
      }, {
        "lat": 17.4686908721924,
        "lng": 121.222190856934
      }, {
        "lat": 17.4670391082764,
        "lng": 121.223297119141
      }, {
        "lat": 17.4664001464845,
        "lng": 121.224548339844
      }, {
        "lat": 17.4666004180909,
        "lng": 121.225120544434
      }, {
        "lat": 17.4672203063965,
        "lng": 121.22599029541
      }, {
        "lat": 17.4665393829346,
        "lng": 121.227531433105
      }, {
        "lat": 17.465030670166,
        "lng": 121.228500366211
      }, {
        "lat": 17.434539794922,
        "lng": 121.243347167969
      }, {
        "lat": 17.425350189209,
        "lng": 121.185852050781
      }, {
        "lat": 17.4241600036622,
        "lng": 121.179397583008
      }, {
        "lat": 17.4271106719971,
        "lng": 121.159126281738
      }
    ]
  }
};

enter image description here


-1

我尝试了 Twitter 地理 API,但失败了。

Google 地图 API 也失败了,到目前为止,没有任何 API 可以获取城市边界。

Twitter API 的地理终端点不会提供城市边界,

他们提供的仅是带有 5 个点(纬度、经度)的边界框。

这是我从 Twitter API 获取的旧金山边界框 enter image description here


-10
请使用以下代码:

<iframe width="600" height="450" frameborder="0" style="border:0" src="https://www.google.com/maps/embed/v1/place?q=place_id:ChIJ5Rw5v9dCXz4R3SUtcL5ZLMk&key=..." allowfullscreen></iframe>


2
请编辑您的答案,解释为什么这段代码可以回答问题。 - André Kool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接