Google Maps API的哪些组件用于生成绘制多个地址的地图?

时间:2015-10-28 07:26:39

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

我想创建一个功能与本页右侧非常相似的地图: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')

1 个答案:

答案 0 :(得分: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/stackoverflow/city.sql

data.php

<?php
// Connecting, selecting database
$link = mysql_connect('localhost', 'root', '') or die('Could not connect');
mysql_select_db('stackoverflow') 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"}];

因此,您可以随时以任何语言生成此类数据。