使用谷歌地图API v3来确定国家边界

12

有没有一种方法可以使用Google地图API获取国家边界的多边形坐标值。

3个回答

10

如果你想更好地控制边界的显示,建议使用google.maps.Data图层,而不是Fusion表。例如,在geocodezip示例中的世界地图上,如果你缩小地图,边界将会塌陷成点,这是Fusion表和Fusion Layer的局限性之一。通过Data Layer你可以针对特定边界进行样式设置或隐藏。而Fusion Layer只允许条件样式更改。此外,你还可以添加自己的clickmouseovermouseout监听器,实时更改边界图层等等。当然,有时候Fusion Layer是更好的选择,例如当你的数据包含在Fusion表中时,但如果你需要更多的控制权,则Data Layer是更值得推荐的选择。

在我的下一个工作示例中,我将展示如何使用Data Layer渲染世界国家和美国州边界。当然,你也可以使用自己的边界文件。如果你没有GeoJson版本可用(仅有Shapefiles或KML文件),你可以使用像mapshaper之类的工具将其转换为GeoJson(只需运行:mapshaper -i myshp.shp -o format=geojson out.geo.json)。

var map = null;
  var my_boundaries = {};
  var data_layer;
  var info_window;

  //initialize map on document ready
  $(document).ready(function(){
   var latlng = new google.maps.LatLng(40.723080, -73.984340); //you can use any location as center on map startup
   var myOptions = {
    zoom: 2,
    center: latlng,
    mapTypeControl: true,
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
   };
   map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
   google.maps.event.addListener(map, 'click', function(){
    if(info_window){
     info_window.setMap(null);
     info_window = null;
    }
   });
 
 $('#boundary_load_select').change(function(){
  if($(this).val()==1){
   loadBoundariesFromGeoJson("https://raw.githubusercontent.com/matej-pavla/Google-Maps-Examples/master/BoundariesExample/geojsons/world.countries.geo.json");
  }else{
   loadBoundariesFromGeoJson("https://raw.githubusercontent.com/matej-pavla/Google-Maps-Examples/master/BoundariesExample/geojsons/us.states.geo.json");
  }
 });
 loadBoundariesFromGeoJson("https://raw.githubusercontent.com/matej-pavla/Google-Maps-Examples/master/BoundariesExample/geojsons/world.countries.geo.json");
  });

  function initializeDataLayer(){
 if(data_layer){
  data_layer.forEach(function(feature) {
      data_layer.remove(feature);
  });
  data_layer = null;
 }
 data_layer = new google.maps.Data({map: map}); //initialize data layer which contains the boundaries. It's possible to have multiple data layers on one map
   data_layer.setStyle({ //using set style we can set styles for all boundaries at once
    fillColor: 'white',
    strokeWeight: 1,
    fillOpacity: 0.1
   });

   data_layer.addListener('click', function(e) { //we can listen for a boundary click and identify boundary based on e.feature.getProperty('boundary_id'); we set when adding boundary to data layer
    var boundary_id = e.feature.getProperty('boundary_id');
    var boundary_name = "NOT SET";
    if(boundary_id && my_boundaries[boundary_id] && my_boundaries[boundary_id].name) boundary_name = my_boundaries[boundary_id].name;
    if(info_window){
     info_window.setMap(null);
     info_window = null;
    }
    info_window = new google.maps.InfoWindow({
     content: '<div>You have clicked a boundary: <span style="color:red;">' + boundary_name + '</span></div>',
     size: new google.maps.Size(150,50),
     position: e.latLng, map: map
    });
   });
 
 data_layer.addListener('mouseover', function(e) {
  data_layer.overrideStyle(e.feature, {
   strokeWeight: 3,
   strokeColor: '#ff0000'
  });
 });
 
 data_layer.addListener('mouseout', function(e) {
  data_layer.overrideStyle(e.feature, {
   strokeWeight: 1,
   strokeColor: ''
  });
 });
  }

  function loadBoundariesFromGeoJson(geo_json_url){
 initializeDataLayer();
   $.getJSON(geo_json_url, function(data){
    if(data.type == "FeatureCollection"){ //we have a collection of boundaries in geojson format
     if(data.features){
      for(var i = 0; i < data.features.length; i++){
     var boundary_id = i + 1;
       var new_boundary = {};
       if(!data.features[i].properties) data.features[i].properties = {}; 
     data.features[i].properties.boundary_id = boundary_id; //we will use this id to identify boundary later when clicking on it
       data_layer.addGeoJson(data.features[i], {idPropertyName: 'boundary_id'});
     new_boundary.feature = data_layer.getFeatureById(boundary_id);
       if(data.features[i].properties.name) new_boundary.name = data.features[i].properties.name;
     if(data.features[i].properties.NAME) new_boundary.name = data.features[i].properties.NAME;
       my_boundaries[boundary_id] = new_boundary;
      }
     }
   if(my_boundaries[24]){ //just an example, that you can change styles of individual boundary
    data_layer.overrideStyle(my_boundaries[24].feature, {
     fillColor: '#0000FF',
     fillOpacity: 0.9
    });
   }
    }
   });
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("maps", "3",{other_params:"sensor=false"});
</script>
<body style="margin:0px; padding:0px;" >
 <select id="boundary_load_select">
  <option value="1">Load World Boundaries</option>
  <option value="2">Load US States Boundaries</option>
 </select>
 <div id="map_canvas" style="height:400px; width:500px;"></div>
</body>


嘿,谢谢你,伙计。我一直在寻找URL,但是你的内部链接对我很有用,谢谢。如果你们需要关于绘制国家边界的帮助,请告诉我。 - ashokdy
除了美国以外,我如何获取其他国家的州坐标? - Noushad
这个问题并没有统一的答案。对于某些国家,你甚至可能无法获取到它们。对于美国、澳大利亚,我认为新西兰和加拿大也是如此,你可以找到人口普查数据,边界通常是可用的。例如英国有Ordnance Survey。对于一些国家,我根本找不到它们,而对于一些国家,它们是付费的。所以你需要谷歌一下。 - Matej P.
我怎样可以在zip级别上完成它? - Sana Ahmed
1
你需要从国家边界开始,但是你必须找到邮政编码边界的数据,这取决于国家:对于美国,你可以在(https://www.census.gov/cgi-bin/geo/shapefiles/index.php)找到它们,对于澳大利亚也是如此,对于一些国家,它们是付费的,对于一些国家,我根本找不到...所以你必须搜索,没有一个地方可以得到所有的数据...然而,邮政编码的问题是,通常有太多的多边形需要浏览器处理。关于如何解决这个问题,请参考这个答案:https://dev59.com/kpbfa4cB1Zd3GeqPzt30#37167093 - Matej P.
你是如何获取国家和州的边界的? - - 这里有一个案例,我想找到这些国家的JSON文件,以便我可以可视化这些变量。https://webapps.stackexchange.com/q/108181/66725 - Léo Léopold Hertz 준영

10

参考这个类似的问题:Google Maps V3: Draw German State Polygons?

FusionTables中的自然地球数据集中包含有国家多边形。您可以按照您的喜好来设计它们。

我用它创建了这个例子:http://www.geocodezip.com/v3_FusionTablesLayer_worldmap_linkto.html

这是一个使用KmlLayer的例子:http://www.geocodezip.com/v3_GoogleEx_layer-kml_world_countries_simple.html

代码片段:

var kmlLayer = null;
var map = null;

function openIW(layerEvt) {
  if (layerEvt.row) {
    var content = layerEvt.row['admin'].value;
  } else if (layerEvt.featureData) {
    var content = layerEvt.featureData.name;
  }
  document.getElementById('info').innerHTML = "you clicked on:<br>" + content;
}

function initialize() {
  var chicago = new google.maps.LatLng(36.4278, -15.9);
  var myOptions = {
    zoom: 0,
    center: chicago,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }

  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  google.maps.event.addListener(map, "click", function() {
    document.getElementById('info').innerHTML = "";
  });


  kmlLayer = new google.maps.KmlLayer('http://www.geocodezip.com/geoxml3_test/world_countries_kml.xml', {
    preserveViewport: true,
    suppressInfoWindows: true
  });
  kmlLayer.setMap(map);

  google.maps.event.addListener(kmlLayer, 'click', openIW);
}
google.maps.event.addDomListener(window, 'load', initialize);
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<table>
  <tr>
    <td>
      <div id="map_canvas" style="height:200px; width:300px;"></div>
    </td>
    <td>
      <div id="info"></div>
    </td>
  </tr>
</table>


你的例子可以扩展到两个国家吗? - Léo Léopold Hertz 준영
当然可以。我不确定你在问哪个示例,但那听起来像是另一个问题。 - geocodezip
是的,没错。我在思考是否可以通过你的代码库来可视化两个国家和/或更多国家。 - Léo Léopold Hertz 준영
你有预览的代码吗?我想为绘图提供一个列表。 - Léo Léopold Hertz 준영
1
你是指 view-source 吗?我不明白你所说的“我想为绘图提供一个列表”的意思(但这不是评论的主题,而是一个新问题)。 - geocodezip

0

我猜你想在边界上绘制多边形。为此,您必须知道将帮助绘制多边形的坐标。我只为美国做过这件事。我拥有所有州的坐标。我在每个州上绘制多边形。这使美国突出显示。

您可以查看我的问题以获取美国解决方案。但是对于其他国家,您必须了解坐标。


我想为都柏林绘制多边形,但不知道坐标,这种情况下我该如何绘制多边形? - Shital Jachak

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