【问题标题】:What component(s) of the Google Maps API is used to generate maps plotting many addresses?Google Maps API 的哪些组件用于生成绘制多个地址的地图?
【发布时间】:2026-02-06 20:55:02
【问题描述】:

我想创建一个功能与此页面右侧的地图非常相似的地图:https://spacelist.ca/search

  • 从地理编码地址组件数据库中绘制地址
  • 缩小时,将附近的地址数量显示为可点击的数字
  • 点击数字会放大,数字会分成更小的辖区
  • 侧面板列出了在地图边缘可见的城市/社区/校园/地址
  • 单击图钉可在侧面板上显示有关该地址的信息
  • 在侧面板上选择某些内容将显示到地图上的相应区域或图钉

我使用 Django 作为后端。

我打开他们的/application.c720f8945a.js 并在 VS 中水平滚动导致幻灯片放映。即使它是正确的地方,也有太多的东西,我不知道我到底在找什么。

我不知道如何或从哪里开始,也不知道我应该为这种地图使用什么搜索词。如果有人能指出如何开始的正确方向,我将不胜感激。

models.py

class Address(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    creator = models.ForeignKey(User, related_name='Address_created')
    owner = models.ForeignKey(User, null=True, related_name='Address_owned')
    visible = models.BooleanField(default=False)
    street_number = models.CharField(max_length=255)
    route = models.ForeignKey(Route)
    postal_code = models.CharField(max_length=7, blank=True)
    lat = models.FloatField()
    lng = models.FloatField()
    rating = models.FloatField(default=0)
    class Meta:
        unique_together = ('street_number', 'route')

【问题讨论】:

  • 对一个问题有很多要求。这是可行的;很多。让我们从数据开始。向我展示您拥有的数据样本。给我看你的数据库表(结构)。是 php/mySQL 吗?你有坐标吗,或者你希望谷歌地图每次都使用地理编码(我建议你搜索一次,然后将坐标添加到你的数据库中)?
  • 用型号代码更新了 OP。它在 Python 中,Django 将其转换为 SQL。是的,用户添加新地址时搜索一次,坐标保存为一对浮点数。

标签: javascript jquery django google-maps google-maps-api-3


【解决方案1】:

我必须用 php 和 mySQL 来回答,对不起。

我认为,这是一个可以解决您大部分问题的示例。与比利时城镇。

小出口:

CREATE TABLE IF NOT EXISTS city ( id bigint(15) NOT NULL, alpha varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, longitude decimal(12,10) DEFAULT NULL, latitude decimal(12,10) DEFAULT NULL, code varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, name varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, province bigint(15) NOT NULL DEFAULT '0', PRIMARY KEY (id), KEY region (province), KEY code (code), KEY alpha (alpha) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci; INSERT INTO city (id, alpha, longitude, latitude, code, name, province) VALUES (2753, 'vodele', 4.7319823000, 50.1700235000, '5680', 'Vodelée', 10), (2752, 'vaucelles', 4.7435856000, 50.1132065000, '5680', 'Vaucelles', 10), (2751, 'soulme', 4.7362843000, 50.1875880000, '5680', 'Soulme', 10), (2750, 'romere', 4.6751612000, 50.1349753000, '5680', 'Romerée', 10), (2749, 'niverle', 4.7009273000, 50.1176372000, '5680', 'Niverlée', 10), (2748, 'matagne-la-petite', 4.6466011000, 50.1187174000, '5680', 'Matagne-la-Petite', 10), (2747, 'matagne-la-grande', 4.6230829000, 50.1171994000, '5680', 'Matagne-la-Grande', 10), (2746, 'gochene', 4.7598303000, 50.1838389000, '5680', 'Gochenée', 10), (2745, 'gimne', 4.7141846000, 50.1322987000, '5680', 'Gimnée', 10), (2744, 'doische', 4.7451565000, 50.1354941000, '5680', 'Doische', 10), (2743, 'viroinval', 4.6059942000, 50.0714722000, '5670', 'Viroinval', 10), (2742, 'vierves-sur-viroin', 4.6342325000, 50.0803073000, '5670', 'Vierves-sur-Viroin', 10), (2741, 'treignes', 4.6692223000, 50.0928419000, '5670', 'Treignes', 10), (2740, 'olloy-sur-viroin', 4.6073551000, 50.0734406000, '5670', 'Olloy-sur-Viroin', 10), (2739, 'oignies-en-thirache', 4.6390911000, 50.0237916000, '5670', 'Oignies-en-Thiérache', 10), (2738, 'nismes', 4.5483014000, 50.0747916000, '5670', 'Nismes', 10), (2737, 'maze', 4.6962280000, 50.1013002000, '5670', 'Mazée', 10), (2736, 'le-mesnil', 4.6714057000, 50.0315066000, '5670', 'Le Mesnil', 10), (2735, 'dourbes', 4.5911852000, 50.0915244000, '5670', 'Dourbes', 10), (2734, 'presgaux', 4.4198508000, 50.0251800000, '5660', 'Presgaux', 10), (2733, 'petite-chapelle', 4.5051169000, 49.9501137000, '5660', 'Petite-Chapelle', 10), (2732, 'petigny', 4.5329342000, 50.0588019000, '5660', 'Petigny', 10), (2731, 'pesche', 4.4587268000, 50.0423745000, '5660', 'Pesche', 10), (2730, 'mariembourg', 4.5221759000, 50.0949510000, '5660', 'Mariembourg', 10), (2729, 'gonrieux', 4.4262188000, 50.0360473000, '5660', 'Gonrieux', 10), (2728, 'frasnes-namur', 4.5089143000, 50.0767425000, '5660', 'Frasnes, Namur', 10), (2727, 'dailly', 4.4357088000, 50.0574819000, '5660', 'Dailly', 10), (2726, 'cul-des-sarts', 4.4546930000, 49.9620803000, '5660', 'Cul-des-Sarts', 10), (2725, 'couvin', 4.4971552000, 50.0516936000, '5660', 'Couvin', 10), (2724, 'brly-de-pesche', 4.4607012000, 50.0009904000, '5660', 'Brûly-de-Pesche', 10), (2723, 'brly', 4.5276734000, 49.9700584000, '5660', 'Brûly', 10), (2722, 'boussu-en-fagne', 4.4718043000, 50.0762654000, '5660', 'Boussu-en-Fagne', 10), (2721, 'aublain', 4.4090755000, 50.0675767000, '5660', 'Aublain', 10), (2720, 'thy-le-chteau', 4.4259158000, 50.2823570000, '5651', 'Thy-le-Château', 10), (2719, 'tarcienne', 4.4978154000, 50.3121148000, '5651', 'Tarcienne', 10), (2718, 'somze', 4.4831638000, 50.2950667000, '5651', 'Somzée', 10), (2717, 'rogne', 4.3890376000, 50.2696666000, '5651', 'Rognée', 10), (2716, 'laneffe', 4.4945456000, 50.2776590000, '5651', 'Laneffe', 10), (2715, 'gourdinne', 4.4562301000, 50.2901206000, '5651', 'Gourdinne', 10), (2714, 'berze', 4.3991598000, 50.2906721000, '5651', 'Berzée', 10), (2713, 'yves-gomeze', 4.4942942000, 50.2394220000, '5650', 'Yves-Gomezée', 10), (2712, 'walcourt', 4.4316899000, 50.2517267000, '5650', 'Walcourt', 10), (2711, 'vogene', 4.4523807000, 50.2388380000, '5650', 'Vogenée', 10), (2710, 'pry', 4.4292602000, 50.2702052000, '5650', 'Pry', 10), (2709, 'fraire', 4.5075507000, 50.2612928000, '5650', 'Fraire', 10), (2708, 'fontenelle', 4.3820441000, 50.2480932000, '5650', 'Fontenelle', 10), (2707, 'clermont-namur', 4.3166534000, 50.2602509000, '5650', 'Clermont, Namur', 10), (2706, 'chastrs', 4.4594299000, 50.2649875000, '5650', 'Chastrès', 10), (2705, 'castillon', 4.3535680000, 50.2469600000, '5650', 'Castillon', 10), (2704, 'stave', 4.6595389000, 50.2823372000, '5646', 'Stave', 10), (2703, 'ermeton-sur-biert', 4.7220269000, 50.2886049000, '5644', 'Ermeton-sur-Biert', 10), (2702, 'furnaux', 4.7035401000, 50.3074423000, '5641', 'Furnaux', 10), (2701, 'saint-grard', 4.7402044000, 50.3459587000, '5640', 'Saint-Gérard', 10), (2700, 'oret', 4.6155651000, 50.2998711000, '5640', 'Oret', 10), (2699, 'mettet', 4.6579476000, 50.3201538000, '5640', 'Mettet', 10), (2698, 'graux', 4.7188075000, 50.3256276000, '5640', 'Graux', 10), (2697, 'biesmere', 4.6800577000, 50.2972765000, '5640', 'Biesmerée', 10), (2696, 'biesme', 4.6084738000, 50.3341410000, '5640', 'Biesme', 10), (2695, 'villers-deux-eglises', 4.4827135000, 50.1895479000, '5630', 'Villers-Deux-Eglises', 10), (2694, 'soumoy', 4.4374719000, 50.1893197000, '5630', 'Soumoy', 10), (2693, 'silenrieux', 4.4101535000, 50.2247693000, '5630', 'Silenrieux', 10), (2692, 'senzeille', 4.4654506000, 50.1773954000, '5630', 'Senzeille', 10), (2691, 'daussois', 4.4538610000, 50.2215797000, '5630', 'Daussois', 10), (2690, 'cerfontaine', 4.4123064000, 50.1706980000, '5630', 'Cerfontaine', 10), (2689, 'thy-le-bauduin', 4.5236966000, 50.2951273000, '5621', 'Thy-le-Bauduin', 10), (2688, 'morialm', 4.5659309000, 50.2750372000, '5621', 'Morialmé', 10), (2687, 'hanzinne', 4.5431971000, 50.3100157000, '5621', 'Hanzinne', 10), (2686, 'hanzinelle', 4.5564457000, 50.2960690000, '5621', 'Hanzinelle', 10), (2685, 'saint-aubin', 4.5775596000, 50.2480443000, '5620', 'Saint-Aubin', 10), (2684, 'rose', 4.6867744000, 50.2321287000, '5620', 'Rosée', 10), (2683, 'morville', 4.7449983000, 50.2334567000, '5620', 'Morville', 10), (2682, 'hemptinne-lez-florennes', 4.5626703000, 50.2285443000, '5620', 'Hemptinne-lez-Florennes', 10), (2681, 'florennes', 4.6037449000, 50.2508165000, '5620', 'Florennes', 10), (2680, 'flavion', 4.7122250000, 50.2492740000, '5620', 'Flavion', 10), (2679, 'corenne', 4.6787666000, 50.2522483000, '5620', 'Corenne', 10);

更大的文件:http://www.manutechnica.com/*/city.sql

数据.php

<?php
// Connecting, selecting database
$link = mysql_connect('localhost', 'root', '') or die('Could not connect');
mysql_select_db('*') or die('Could not select database');
mysql_set_charset('utf8',$link);

$query = 'SELECT id, latitude as lat, longitude as lng, name, code FROM city';
$res = mysql_query($query);

$my_array = array();
while ($row = mysql_fetch_assoc($res)) {
  array_push ($my_array, $row);
}

// print the result
echo json_encode($my_array);
// Free resultset
mysql_free_result($res);
// Closing connection
mysql_close($link);
?>

index.php

<style>
#map {
  height: 400px;
}
#display {
  max-height: 400px;
  overflow-y: auto;
  cursor: pointer;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclustererplus/src/markerclusterer.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
  var mc;
  var map;
  var markers = [];
  var markerData = [];
  function initialize() {

    map = new google.maps.Map(document.getElementById('map'), {
      zoom: 12,
      center: new google.maps.LatLng(51, 4),  // Belgium
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    // Read the locations from database, with an Ajax call
    getData(function(data) {
      markerData = data;
      // infowindow
      var infowindow = new google.maps.InfoWindow({
        map: map,
        content: ''
      });
      for (var i in data) {
        var marker = new google.maps.Marker({
          map: map,
          position: new google.maps.LatLng(data[i].lat, data[i].lng),
          title: data[i].name
        });
        markers.push(marker);
        marker.addListener('click', function() {
          //first see which marker was clicked upon
          var index = markers.indexOf(this);
          var content = markerData[index].name +'<br>postal code: '+ markerData[index].code; //feel free to add tags
          infowindow.open(map, markers[index]);
          infowindow.setContent(content);
        });
      }

      // now cluster the markers
      var mcOptions = {}; //{gridSize: 50, maxZoom: 15};
      mc = new MarkerClusterer(map, markers, mcOptions);
      google.maps.event.addListener(map, 'bounds_changed', function() {
        document.getElementById('display').innerHTML = '';
        var newContent = '';
        for (var i in markers) {
          if (markerIsInSight(markers[i])) {
            newContent += '<li onclick="zoomTo(' + i + ')">' + markerData[i].name +' - postal code: '+ markerData[i].code +'</li>';
          }
        }
        document.getElementById('display').innerHTML = newContent;
      });
    });

    function markerIsInSight(marker) {
      // Let's consider a rectangle, we have map boundaries.  
      // Notice, for big countries like Canada (especially when they're close to a pole), a trapezium would be better; the map shows more difference of longitude in the north than in the south, due to the curvature of earth.
      return ( // returns true or false
        marker.getPosition().lat() <= map.getBounds().getNorthEast().lat()  &&
        marker.getPosition().lat() >= map.getBounds().getSouthWest().lat()  &&
        marker.getPosition().lng() <= map.getBounds().getNorthEast().lng()  &&
        marker.getPosition().lng() >= map.getBounds().getSouthWest().lng()  
      );  
    }
  }

  // Read the locations from database, with an Ajax call
  // callback is a function that will be executed when Ajax returns with data from the server
  function getData(callback) {
      $.ajax({
        url: 'data.php',
        dataType: 'json',
        success: function(data) {
          callback(data);
        }
      });
  }

  function zoomTo(index) {
    map.setZoom(15);
    map.setCenter(markers[index].getPosition());
  }

  google.maps.event.addDomListener(window, 'load', initialize);
</script>
<div id="map"></div>
<ul id="display"></ul>

data.php 生成如下数据:

[{"id":"1032","lat":"51.1014829000","lng":"2.8909046000","name":"Leke","code":"8600"},{"id":"1031","lat":"51.0325201000","lng":"2.7683533000","name":"Lampernisse","code":"8600"},{"id":"1030","lat":"51.0814378000","lng":"2.8821894000","name":"Keiem","code":"8600"},{"id":"1029","lat":"51.0364146000","lng":"2.8367637000","name":"Kaaskerke","code":"8600"},{"id":"1028","lat":"51.0294638000","lng":"2.9021306000","name":"Esen","code":"8600"},{"id":"1027","lat":"50.7064502000","lng":"3.9865752000","name":"Driekapellen","code":"8600"},{"id":"1026","lat":"51.0317985000","lng":"2.8637681000","name":"Diksmuide","code":"8600"},{"id":"1025","lat":"51.0588750000","lng":"2.8869089000","name":"Beerst","code":"8600"}];

因此,您可以随意以任何您知道的任何语言、任何方式生成这样的数据。

【讨论】:

  • “Marker clusters”是我要找的搜索词!我现在已经掌握了所有的拼图,成功实施它只是时间问题。您在index.php 中的 JS 将真正帮助指导我完成此过程。非常感谢!