javascript شرح - Google Maps JS API v3-Simple Marker Example




icons add (10)

جديد تمامًا على Google Maps Api. لقد حصلت على مجموعة من البيانات التي أرغب في التنقل خلالها ووضع خريطة على خريطة. يبدو بسيطًا إلى حدٍ ما ، ولكن جميع البرامج التعليمية المتعددة التي أجدها معقدة للغاية.

دعونا نستخدم مصفوفة البيانات من موقع google على سبيل المثال:

var locations = [
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

أنا ببساطة أريد أن أرسم كل هذه النقاط وأظهر نافذة منبثقة عند النقر لعرض الاسم.


Answers

إجابة مقبولة ، تمت إعادة كتابتها في ES6:

$(document).ready(() => {
  const mapEl = $('#our_map').get(0); // OR document.getElementById('our_map');

  // Display a map on the page
  const map = new google.maps.Map(mapEl, { mapTypeId: 'roadmap' });

  const buildings = [
    {
      title: 'London Eye, London', 
      coordinates: [51.503454, -0.119562],
      info: 'carousel'
    },
    {
      title: 'Palace of Westminster, London', 
      coordinates: [51.499633, -0.124755],
      info: 'palace'
    }
  ];

  placeBuildingsOnMap(buildings, map);
});


const placeBuildingsOnMap = (buildings, map) => {
  // Loop through our array of buildings & place each one on the map  
  const bounds = new google.maps.LatLngBounds();
  buildings.forEach((building) => {
    const position = { lat: building.coordinates[0], lng: building.coordinates[1] }
    // Stretch our bounds to the newly found marker position
    bounds.extend(position);

    const marker = new google.maps.Marker({
      position: position,
      map: map,
      title: building.title
    });

    const infoWindow = new google.maps.InfoWindow();
    // Allow each marker to have an info window
    google.maps.event.addListener(marker, 'click', () => {
      infoWindow.setContent(building.info);
      infoWindow.open(map, marker);
    })

    // Automatically center the map fitting all markers on the screen
    map.fitBounds(bounds);
  })
})

ظننت أنني سأضع هذا هنا حيث يبدو أنها نقطة هبوط شعبية لأولئك الذين بدأوا في استخدام API لخرائط Google. من المحتمل أن تكون العديد من الواجهات التي يتم عرضها على جانب العميل هي سقوط العديد من تطبيقات أداء الخرائط. من الصعب قياس ، إصلاح ، وفي بعض الحالات حتى تنشأ هناك مشكلة (بسبب اختلافات تنفيذ المتصفح ، الأجهزة المتاحة للعميل ، أجهزة المحمول ، القائمة تستمر).

تتمثل أبسط طريقة للبدء في معالجة هذه المشكلة في استخدام حل مجموعة علامات. الفكرة الأساسية هي تجميع المواقع المتشابهة جغرافيًا في مجموعة مع عدد النقاط المعروضة. عندما يعمد المستخدم إلى تكبير الخريطة ، تتوسع هذه المجموعات لتكشف عن علامات فردية أسفلها.

ولعل أبسطها هي مكتبة markerclusterer . التنفيذ الأساسي سيكون على النحو التالي (بعد استيراد المكتبة):

<script type="text/javascript">
  function initialize() {
    var center = new google.maps.LatLng(37.4419, -122.1419);

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 3,
      center: center,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var markers = [];
    for (var i = 0; i < 100; i++) {
      var location = yourData.location[i];
      var latLng = new google.maps.LatLng(location.latitude,
          location.longitude);
      var marker = new google.maps.Marker({
        position: latLng
      });
      markers.push(marker);
    }
    var markerCluster = new MarkerClusterer(map, markers);
  }
  google.maps.event.addDomListener(window, 'load', initialize);
</script>

تتم إضافة العلامات بدلاً من إضافتها مباشرةً إلى الخريطة إلى مصفوفة. ثم يتم تمرير هذا الصفيف إلى المكتبة التي تتعامل مع الحسابات المعقدة لك وترتبط بالخريطة.

لا تؤدي هذه التطبيقات إلى زيادة أداء العميل بشكل كبير فحسب ، بل تؤدي أيضًا في كثير من الحالات إلى واجهة مستخدم أبسط وأقل فوضى وتسهل عملية هضم البيانات على نطاق أوسع.

تتوفر تطبيقات أخرى من Google.

نأمل أن يساعد هذا بعض من تلك أحدث إلى الفروق الدقيقة في رسم الخرائط.


من إجابة دانيال فاسالو ، هنا نسخة تتعامل مع قضية الإغلاق بطريقة أبسط.

نظرًا لأن كافة العلامات ستحتوي على InfoWindow فردي وحيث إن JavaScript لا تهتم إذا قمت بإضافة خصائص إضافية إلى كائن ما ، فكل ما عليك فعله هو إضافة InfoWindow إلى خصائص Marker ثم الاتصال بـ .open() على InfoWindow من بحد ذاتها!

تحرير: مع بيانات كافية ، يمكن أن يستغرق pageload الكثير من الوقت ، بدلاً من إنشاء InfoWindow مع العلامة ، يجب أن يحدث البناء فقط عند الحاجة. لاحظ أن أي بيانات تستخدم لإنشاء InfoWindow يجب إلحاقها بالعلامة كخاصية ( data ). لاحظ أيضًا أنه بعد حدث النقرة الأول ، infoWindow ، لذلك لا يحتاج المتصفح إلى إعادة infoWindow باستمرار.

var locations = [
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

var map = new google.maps.Map(document.getElementById('map'), {
  center: new google.maps.LatLng(-33.92, 151.25)
});

for (i = 0; i < locations.length; i++) {  
  marker = new google.maps.Marker({
    position: new google.maps.LatLng(locations[i][1], locations[i][2]),
    map: map,
    data: {
      name: locations[i][0]
    }
  });
  marker.addListener('click', function() {
    if(!this.infoWindow) {
      this.infoWindow = new google.maps.InfoWindow({
        content: this.data.name;
      });
    }
    this.infoWindow.open(map,this);
  })
}

هذا هو أبسط ما يمكن أن أخفضه إلى:

<!DOCTYPE html>
<html> 
<head> 
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 
  <title>Google Maps Multiple Markers</title> 
  <script src="http://maps.google.com/maps/api/js?sensor=false" 
          type="text/javascript"></script>
</head> 
<body>
  <div id="map" style="width: 500px; height: 400px;"></div>

  <script type="text/javascript">
    var locations = [
      ['Bondi Beach', -33.890542, 151.274856, 4],
      ['Coogee Beach', -33.923036, 151.259052, 5],
      ['Cronulla Beach', -34.028249, 151.157507, 3],
      ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
      ['Maroubra Beach', -33.950198, 151.259302, 1]
    ];

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 10,
      center: new google.maps.LatLng(-33.92, 151.25),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var infowindow = new google.maps.InfoWindow();

    var marker, i;

    for (i = 0; i < locations.length; i++) {  
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });

      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }
  </script>
</body>
</html>

لقطة شاشة:

هناك بعض إغلاق addListener يحدث عند تمرير الوسيطة رد الاتصال إلى أسلوب addListener . قد يكون هذا موضوعًا صعبًا للغاية ، إذا لم تكن على دراية بكيفية عمل الإغلاق. أقترح مراجعة مقالة Mozilla التالية للحصول على مقدمة موجزة ، إذا كان الأمر كذلك:


var arr = new Array();
    function initialize() { 
        var i;  
        var Locations = [
                {
                  lat:48.856614, 
                  lon:2.3522219000000177, 
                  address:'Paris',
                  gval:'25.5',
                  aType:'Non-Commodity',
                  title:'Paris',
                  descr:'Paris'           
                },        
                    {
                  lat: 55.7512419, 
                  lon: 37.6184217,
                  address:'Moscow',
                  gval:'11.5',
                  aType:'Non-Commodity',
                  title:'Moscow',
                  descr:'Moscow Airport'              
                },     

                {
              lat:-9.481553000000002, 
              lon:147.190242, 
              address:'Port Moresby',
              gval:'1',
              aType:'Oil',
              title:'Papua New Guinea',
              descr:'Papua New Guinea 123123123'              
            },
            {
           lat:20.5200,
           lon:77.7500,
           address:'Indore',
            gval:'1',
            aType:'Oil',
            title:'Indore, India',
            descr:'Airport India'
        }
    ];

    var myOptions = {
        zoom: 2,
        center: new google.maps.LatLng(51.9000,8.4731),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

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

    var infowindow =  new google.maps.InfoWindow({
        content: ''
    });

    for (i = 0; i < Locations.length; i++) {
            size=15;        
            var img=new google.maps.MarkerImage('marker.png',           
                new google.maps.Size(size, size),
                new google.maps.Point(0,0),
                new google.maps.Point(size/2, size/2)
           );

        var marker = new google.maps.Marker({
            map: map,
            title: Locations[i].title,
            position: new google.maps.LatLng(Locations[i].lat, Locations[i].lon),           
                icon: img
        });

        bindInfoWindow(marker, map, infowindow, "<p>" + Locations[i].descr + "</p>",Locations[i].title);  

    }

}

function bindInfoWindow(marker, map, infowindow, html, Ltitle) { 
    google.maps.event.addListener(marker, 'mouseover', function() {
            infowindow.setContent(html); 
            infowindow.open(map, marker); 

    });
    google.maps.event.addListener(marker, 'mouseout', function() {
        infowindow.close();

    }); 
} 

مثال كامل على العمل. يمكنك فقط النسخ واللصق والاستخدام.


هنا نسخة أخرى كتبت من أجل حفظ خريطة العقارات ، والتي تضع مؤشر infowindow على lat الحقيقي و long of the marker ، بينما تخفي مؤقتًا العلامة أثناء عرض infowindow.

كما أنه يلغي المهمة "علامة" القياسية ويسرع عملية المعالجة عن طريق تعيين علامة جديدة مباشرة إلى صف محددات على إنشاء علامات. لاحظ مع ذلك ، أنه تمت إضافة خصائص إضافية إلى كل من العلامة والإنفراج ، لذلك فإن هذا النهج هو صبي غير تقليدي ... ولكن هذا أنا!

لا يتم ذكرها أبداً في أسئلة infowindow هذه ، التي لا يتم وضع infowindow القياسي في lat و lng نقطة علامة ولكن بدلاً من ذلك في أعلى صورة العلامة. يجب إخفاء مستوى رؤية العلامة حتى يعمل ذلك ، وإلا فإن واجهة برمجة تطبيقات الخرائط ستجعل مرساة infowindow ترجع إلى أعلى صورة العلامة مرة أخرى.

يتم إنشاء إشارة إلى العلامات الموجودة في مصفوفة "العلامات" فورًا عند إعلان العلامة لأي مهام معالجة إضافية قد تكون مطلوبة في وقت لاحق (إخفاء / إظهار ، الاستيلاء على الحبال ، الخ ...). يؤدي هذا إلى حفظ الخطوة الإضافية لتعيين كائن العلامة إلى "علامة" ، ثم دفع "العلامة" إلى مجموعة علامات ... الكثير من المعالجة غير الضرورية في كتابي.

على أي حال ، تأخذ مختلفة على infowindows ، ونأمل أن يساعد على إعلام وإلهام لك.

    var locations = [
      ['Bondi Beach', -33.890542, 151.274856, 4],
      ['Coogee Beach', -33.923036, 151.259052, 5],
      ['Cronulla Beach', -34.028249, 151.157507, 3],
      ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
      ['Maroubra Beach', -33.950198, 151.259302, 1]
    ];
    var map;
    var markers = [];

    function init(){
      map = new google.maps.Map(document.getElementById('map_canvas'), {
        zoom: 10,
        center: new google.maps.LatLng(-33.92, 151.25),
        mapTypeId: google.maps.MapTypeId.ROADMAP
      });

      var num_markers = locations.length;
      for (var i = 0; i < num_markers; i++) {  
        markers[i] = new google.maps.Marker({
          position: {lat:locations[i][1], lng:locations[i][2]},
          map: map,
          html: locations[i][0],
          id: i,
        });

        google.maps.event.addListener(markers[i], 'click', function(){
          var infowindow = new google.maps.InfoWindow({
            id: this.id,
            content:this.html,
            position:this.getPosition()
          });
          google.maps.event.addListenerOnce(infowindow, 'closeclick', function(){
            markers[this.id].setVisible(true);
          });
          this.setVisible(false);
          infowindow.open(map);
        });
      }
    }

google.maps.event.addDomListener(window, 'load', init);

هنا هو JSFiddle العمل

مذكرة إضافية
ستلاحظ في هذا المثال بيانات Google المعينة مكانًا رابعًا في مصفوفة "المواقع" برقم. بالنظر إلى هذا في المثال ، يمكنك أيضًا استخدام هذه القيمة لمعرف العلامة بدلاً من قيمة الحلقة الحالية ، بحيث ...

var num_markers = locations.length;
for (var i = 0; i < num_markers; i++) {  
  markers[i] = new google.maps.Marker({
    position: {lat:locations[i][1], lng:locations[i][2]},
    map: map,
    html: locations[i][0],
    id: locations[i][3],
  });
};

إضافة علامة في برنامجك بسيط جدا. تحتاج فقط إلى إضافة هذا الرمز:

var marker = new google.maps.Marker({
  position: myLatLng,
  map: map,
  title: 'Hello World!'
});

تعتبر الحقول التالية مهمة بشكل خاص ويتم تعيينها بشكل شائع عند إنشاء علامة:

  • يحدد position (مطلوب) خط تحديد خط الطول (LatLng) يحدد الموقع الأولي للعلامة. إحدى طرق استرجاع LatLng هي باستخدام خدمة Geocoding .
  • تحدد map (الاختيارية) الخريطة التي يتم وضع علامة عليها. إذا لم تحدد الخريطة الخاصة ببناء العلامة ، يتم إنشاء العلامة ولكن لا يتم إرفاقها (أو عرضها على) الخريطة. يمكنك إضافة العلامة لاحقًا من خلال استدعاء طريقة setMap() .

لاحظ ، في المثال ، يحدد حقل العنوان عنوان العلامة الذي سيظهر على أنه تلميح أداة.

يمكنك الرجوع إلى وثائق Google API here .

هذا مثال كامل لتعيين علامة واحدة في الخريطة. كن حذرًا تمامًا ، يجب استبدال YOUR_API_KEY بواسطة مفتاح واجهة برمجة تطبيقات google :

<!DOCTYPE html>
<html>
<head>
   <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
   <meta charset="utf-8">
   <title>Simple markers</title>
<style>
  /* Always set the map height explicitly to define the size of the div
   * element that contains the map. */
  #map {
    height: 100%;
  }
  /* Optional: Makes the sample page fill the window. */
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
  }
</style>
</head>
<body>
 <div id="map"></div>
<script>

  function initMap() {
    var myLatLng = {lat: -25.363, lng: 131.044};

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 4,
      center: myLatLng
    });

    var marker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      title: 'Hello World!'
    });
  }
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

الآن ، إذا كنت تريد رسم علامات لصفيف في الخريطة ، فيجب أن تفعل مثل هذا:

var locations = [
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

function initMap() {
  var myLatLng = {lat: -33.90, lng: 151.16};

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: myLatLng
    });

  var count;

  for (count = 0; count < locations.length; count++) {  
    new google.maps.Marker({
      position: new google.maps.LatLng(locations[count][1], locations[count][2]),
      map: map,
      title: locations[count][0]
      });
   }
}

يعطيني هذا المثال النتيجة التالية:

يمكنك أيضًا إضافة infoWindow في دبوسك. أنت فقط بحاجة إلى هذا الرمز:

var marker = new google.maps.Marker({
    position: new google.maps.LatLng(locations[count][1], locations[count][2]),
    map: map
    });

marker.info = new google.maps.InfoWindow({
    content: 'Hello World!'
    });

يمكنك الحصول على وثائق Google حول infoWindows here .

الآن ، يمكننا فتح infoWindow عندما تكون العلامة "clik" كما يلي:

var marker = new google.maps.Marker({
     position: new google.maps.LatLng(locations[count][1], locations[count][2]),
     map: map
     });

marker.info = new google.maps.InfoWindow({
     content: locations [count][0]
     });


google.maps.event.addListener(marker, 'click', function() {  
    // this = marker
    var marker_map = this.getMap();
    this.info.open(marker_map, this);
    // Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
            });

لاحظ أنه يمكنك الحصول على بعض الوثائق حول " Listener here في مطور جوجل.

وأخيرًا ، يمكننا رسم مخطط معلومات في علامة إذا كان المستخدم ينقر عليه. هذا هو الرمز الكامل الخاص بي:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Info windows</title>
    <style>
    /* Always set the map height explicitly to define the size of the div
    * element that contains the map. */
    #map {
        height: 100%;
    }
    /* Optional: Makes the sample page fill the window. */
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }
    </style>
</head>
<body>
    <div id="map"></div>
    <script>

    var locations = [
        ['Bondi Beach', -33.890542, 151.274856, 4],
        ['Coogee Beach', -33.923036, 151.259052, 5],
        ['Cronulla Beach', -34.028249, 151.157507, 3],
        ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
        ['Maroubra Beach', -33.950198, 151.259302, 1]
    ];


    // When the user clicks the marker, an info window opens.

    function initMap() {
        var myLatLng = {lat: -33.90, lng: 151.16};

        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 10,
            center: myLatLng
            });

        var count=0;


        for (count = 0; count < locations.length; count++) {  

            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(locations[count][1], locations[count][2]),
                map: map
                });

            marker.info = new google.maps.InfoWindow({
                content: locations [count][0]
                });


            google.maps.event.addListener(marker, 'click', function() {  
                // this = marker
                var marker_map = this.getMap();
                this.info.open(marker_map, this);
                // Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
                });
        }
    }
    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
</body>
</html>

عادة ، يجب أن يكون لديك هذه النتيجة:


في ما يلي دالة javascript مكتملة تقريبًا ستسمح بعلامات متعددة تم تحديدها في JSONObject.

سيعرض فقط العلامات الموجودة في حدود الخريطة.

هذا مهم حتى لا تقوم بعمل إضافي.

يمكنك أيضًا تعيين حد على العلامات بحيث لا تظهر كمية كبيرة من العلامات (إذا كانت هناك إمكانية لاستخدام شيء ما في استخدامك) ؛

كما أنه لن يعرض علامات إذا لم يتغير مركز الخريطة أكثر من 500 متر.
وهذا أمر مهم لأنه إذا نقر المستخدم على العلامة وسحب الخريطة عن طريق الخطأ أثناء إجراء ذلك ، فلا تريد أن تعيد الخريطة تحميل العلامات.

أرفقت هذه الوظيفة بمستمع الحدث الخاطئ للخريطة بحيث لا تظهر العلامات إلا عندما تكون الخريطة في وضع الخمول وستعيد عرض العلامات بعد حدث مختلف.

في لقطة شاشة الإجراء ، هناك تغيير بسيط في لقطة الشاشة التي تعرض المزيد من المحتوى في infowindow. لصق من pastbin.com

<script src="//pastebin.com/embed_js/uWAbRxfg"></script>


من نماذج API لخرائط Google :

function initialize() {
  var myOptions = {
    zoom: 10,
    center: new google.maps.LatLng(-33.9, 151.2),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"),
                                myOptions);

  setMarkers(map, beaches);
}

/**
 * Data for the markers consisting of a name, a LatLng and a zIndex for
 * the order in which these markers should display on top of each
 * other.
 */
var beaches = [
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

function setMarkers(map, locations) {
  // Add markers to the map

  // Marker sizes are expressed as a Size of X,Y
  // where the origin of the image (0,0) is located
  // in the top left of the image.

  // Origins, anchor positions and coordinates of the marker
  // increase in the X direction to the right and in
  // the Y direction down.
  var image = new google.maps.MarkerImage('images/beachflag.png',
      // This marker is 20 pixels wide by 32 pixels tall.
      new google.maps.Size(20, 32),
      // The origin for this image is 0,0.
      new google.maps.Point(0,0),
      // The anchor for this image is the base of the flagpole at 0,32.
      new google.maps.Point(0, 32));
  var shadow = new google.maps.MarkerImage('images/beachflag_shadow.png',
      // The shadow image is larger in the horizontal dimension
      // while the position and offset are the same as for the main image.
      new google.maps.Size(37, 32),
      new google.maps.Point(0,0),
      new google.maps.Point(0, 32));
      // Shapes define the clickable region of the icon.
      // The type defines an HTML &lt;area&gt; element 'poly' which
      // traces out a polygon as a series of X,Y points. The final
      // coordinate closes the poly by connecting to the first
      // coordinate.
  var shape = {
      coord: [1, 1, 1, 20, 18, 20, 18 , 1],
      type: 'poly'
  };
  for (var i = 0; i < locations.length; i++) {
    var beach = locations[i];
    var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
    var marker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        shadow: shadow,
        icon: image,
        shape: shape,
        title: beach[0],
        zIndex: beach[3]
    });
  }
}

تحتاج فقط إلى إضافة خيارات الخريطة:

scrollwheel: false




javascript google-maps google-maps-api-3