programing

Google Maps API v3에서 여러 마커가 있는 자동 센터 맵

goodsources 2022. 12. 9. 21:55
반응형

Google Maps API v3에서 여러 마커가 있는 자동 센터 맵

3개의 핀/마커가 있는 지도를 표시할 때 사용하는 방법은 다음과 같습니다.

<script>
  function initialize() {
    var locations = [
      ['DESCRIPTION', 41.926979, 12.517385, 3],
      ['DESCRIPTION', 41.914873, 12.506486, 2],
      ['DESCRIPTION', 41.918574, 12.507201, 1]
    ];

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 15,
      center: new google.maps.LatLng(41.923, 12.513),
      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));
    }
  }

  function loadScript() {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&' + 'callback=initialize';
    document.body.appendChild(script);
  }

  window.onload = loadScript;
</script>

<div id="map" style="width: 900px; height: 700px;"></div>

제가 찾고 있는 것은 지도의 중심을 "수동으로" 찾을 필요가 없는 방법입니다.center: new google.maps.LatLng(41.923, 12.513)3개의 좌표를 중심으로 지도를 자동으로 만드는 방법이 있나요?

더 쉬운 방법은 빈칸을 늘려서LatLngBounds2개의 포인트에서 명시적으로 작성하지 않습니다.(자세한 내용은 이 질문을 참조하십시오.)

코드에 다음과 같이 추가됩니다.

//create empty LatLngBounds object
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow();    

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

  //extend the bounds to include each marker's position
  bounds.extend(marker.position);

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

//now fit the map to the newly inclusive bounds
map.fitBounds(bounds);

//(optional) restore the zoom level after the map is done scaling
var listener = google.maps.event.addListener(map, "idle", function () {
    map.setZoom(3);
    google.maps.event.removeListener(listener);
});

이렇게 하면 임의의 개수의 포인트를 사용할 수 있으므로 순서를 미리 알 필요가 없습니다.

데모 jsFiddle은 이쪽:http://jsfiddle.net/x5R63/

위도 최소값과 경도 최소값을 계산해야 할 것 같습니다.다음은 점의 중심을 맞추기 위해 사용하는 함수의 예제입니다.

//Example values of min & max latlng values
var lat_min = 1.3049337;
var lat_max = 1.3053515;
var lng_min = 103.2103116;
var lng_max = 103.8400188;

map.setCenter(new google.maps.LatLng(
  ((lat_max + lat_min) / 2.0),
  ((lng_max + lng_min) / 2.0)
));
map.fitBounds(new google.maps.LatLngBounds(
  //bottom left
  new google.maps.LatLng(lat_min, lng_min),
  //top right
  new google.maps.LatLng(lat_max, lng_max)
));

Angular 9에서는 이 작업을 수행할 수 있습니다.

  import {GoogleMap, GoogleMapsModule} from "@angular/google-maps";
  @ViewChild('Map') Map: GoogleMap; /* Element Map */

  locations = [
   { lat: 7.423568, lng: 80.462287 },
   { lat: 7.532321, lng: 81.021187 },
   { lat: 6.117010, lng: 80.126269 }
  ];

  constructor() {
   var bounds = new google.maps.LatLngBounds();
    setTimeout(() => {
     for (let u in this.locations) {
      var marker = new google.maps.Marker({
       position: new google.maps.LatLng(this.locations[u].lat, 
       this.locations[u].lng),
      });
      bounds.extend(marker.getPosition());
     }

     this.Map.fitBounds(bounds)
    }, 200)
  }

그리고 표시된 위치에 따라 자동으로 지도의 중심이 맞춰집니다.

결과:

여기에 이미지 설명 입력

이 토픽에 대한 모든 답변을 시도해 보았지만, 아래 항목만 제 프로젝트에서 잘 작동했습니다.

각도 7 및 AGM 코어 1.0.0-베타.7

<agm-map [latitude]="lat" [longitude]="long" [zoom]="zoom" [fitBounds]="true">
  <agm-marker latitude="{{localizacao.latitude}}" longitude="{{localizacao.longitude}}" [agmFitBounds]="true"
    *ngFor="let localizacao of localizacoesTec">
  </agm-marker>
</agm-map>

속성[agmFitBounds]="true"agm-marker그리고.[fitBounds]="true"agm-map그 일을 하다

이전 답변을 바탕으로 한 또 다른 구현입니다.

export class MapComponent {
    @ViewChild(GoogleMap) map: GoogleMap;

    markerList = [
        {
            lat: 41.926979,
            lng: 12.517385
        },
        {
            lat: 41.914873,
            lng: 12.506486
        },
        {
            lat: 41.918574, 
            lng: 12.507201
        }
    ]

    centralize() {
        const bounds = new google.maps.LatLngBounds();
        this.markerList.forEach((marker) => {
            bounds.extend(new google.maps.LatLng(marker.lat, marker.lng))
        })
        this.map.fitBounds(bounds)
    }
}

google.maps를 작성할 필요가 없습니다.Marker"는 LatLgng에서 인스턴스를 생성하고 직접 파라미터로 bounds extend 함수에 전달할 수 있습니다.

지도의 정확한 중심을 찾으려면 위도/론 좌표를 픽셀 좌표로 변환한 다음 픽셀 중심을 찾아서 위도/론 좌표로 다시 변환해야 합니다.

적도의 북쪽과 남쪽의 거리에 따라 표류를 알아차리지 못하거나 신경 쓰지 못할 수 있습니다.지도를 보면 표류를 알 수 있어요.setInterval 내의 setCenter(map.getBounds().getCenter())는 적도에 가까워지면 드리프트가 서서히 사라집니다.

다음을 사용하여 위도/론 좌표와 픽셀 좌표를 변환할 수 있습니다.픽셀 좌표는 전체 세계의 평면을 기준으로 하지만, 그 중심을 찾아서 위도/런으로 다시 전환할 수 있습니다.

   var HALF_WORLD_CIRCUMFERENCE = 268435456; // in pixels at zoom level 21
   var WORLD_RADIUS = HALF_WORLD_CIRCUMFERENCE / Math.PI;

   function _latToY ( lat ) {
      var sinLat = Math.sin( _toRadians( lat ) );
      return HALF_WORLD_CIRCUMFERENCE - WORLD_RADIUS * Math.log( ( 1 + sinLat ) / ( 1 - sinLat ) ) / 2;
   }

   function _lonToX ( lon ) {
      return HALF_WORLD_CIRCUMFERENCE + WORLD_RADIUS * _toRadians( lon );
   }

   function _xToLon ( x ) {
      return _toDegrees( ( x - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS );
   }

   function _yToLat ( y ) {
      return _toDegrees( Math.PI / 2 - 2 * Math.atan( Math.exp( ( y - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS ) ) );
   }

   function _toRadians ( degrees ) {
      return degrees * Math.PI / 180;
   }

   function _toDegrees ( radians ) {
      return radians * 180 / Math.PI;
   }

위의 방법으로 지도 경계를 설정하고 줌 레벨을 리셋하는 대신 평균 LAT와 평균 LON을 계산하여 중심점을 그 위치로 설정합니다.모든 lat 값을 latTotal에 합산하고 모든 lon 값을 lontotal로 합산하여 마커 수로 나눕니다.그런 다음 지도 중심점을 평균값으로 설정합니다.

latCenter = latTotal / markercount; lonCenter = lontotal / markercount;

이전 코드를 변경할 수 없는 상황이었기 때문에 중앙점과 줌 레벨을 계산하는 Javascript 기능을 추가했습니다.

//input
var tempdata = ["18.9400|72.8200-19.1717|72.9560-28.6139|77.2090"];

function getCenterPosition(tempdata){
	var tempLat = tempdata[0].split("-");
	var latitudearray = [];
	var longitudearray = [];
	var i;
	for(i=0; i<tempLat.length;i++){
		var coordinates = tempLat[i].split("|");
		latitudearray.push(coordinates[0]);
		longitudearray.push(coordinates[1]);
	}
	latitudearray.sort(function (a, b) { return a-b; });
	longitudearray.sort(function (a, b) { return a-b; });
	var latdifferenece = latitudearray[latitudearray.length-1] - latitudearray[0];
	var temp = (latdifferenece / 2).toFixed(4) ;
	var latitudeMid = parseFloat(latitudearray[0]) + parseFloat(temp);
	var longidifferenece = longitudearray[longitudearray.length-1] - longitudearray[0];
	temp = (longidifferenece / 2).toFixed(4) ;
	var longitudeMid = parseFloat(longitudearray[0]) + parseFloat(temp);
	var maxdifference = (latdifferenece > longidifferenece)? latdifferenece : longidifferenece;
	var zoomvalue;	
	if(maxdifference >= 0 && maxdifference <= 0.0037)  //zoom 17
		zoomvalue='17';
	else if(maxdifference > 0.0037 && maxdifference <= 0.0070)  //zoom 16
		zoomvalue='16';
	else if(maxdifference > 0.0070 && maxdifference <= 0.0130)  //zoom 15
		zoomvalue='15';
	else if(maxdifference > 0.0130 && maxdifference <= 0.0290)  //zoom 14
		zoomvalue='14';
	else if(maxdifference > 0.0290 && maxdifference <= 0.0550)  //zoom 13
		zoomvalue='13';
	else if(maxdifference > 0.0550 && maxdifference <= 0.1200)  //zoom 12
		zoomvalue='12';
	else if(maxdifference > 0.1200 && maxdifference <= 0.4640)  //zoom 10
		zoomvalue='10';
	else if(maxdifference > 0.4640 && maxdifference <= 1.8580)  //zoom 8
		zoomvalue='8';
	else if(maxdifference > 1.8580 && maxdifference <= 3.5310)  //zoom 7
		zoomvalue='7';
	else if(maxdifference > 3.5310 && maxdifference <= 7.3367)  //zoom 6
		zoomvalue='6';
	else if(maxdifference > 7.3367 && maxdifference <= 14.222)  //zoom 5
		zoomvalue='5';
	else if(maxdifference > 14.222 && maxdifference <= 28.000)  //zoom 4
		zoomvalue='4';
	else if(maxdifference > 28.000 && maxdifference <= 58.000)  //zoom 3
		zoomvalue='3';
	else
		zoomvalue='1';
	return latitudeMid+'|'+longitudeMid+'|'+zoomvalue;
}

이 문제에 대한 제 의견은 다음과 같습니다.

중 하나를 되는 것을 할 수 .lat ★★★★★★★★★★★★★★★★★」lng.

따로따로 .lat ★★★★★★★★★★★★★★★★★」lng각 요소의 평균을 구합니다.이 평균이 중심이 되어야 합니다(또한 테스트 케이스에서도 마찬가지임이 증명되었습니다).

var coords = "50.0160001,3.2840073|50.014458,3.2778274|50.0169713,3.2750587|50.0180745,3.276742|50.0204038,3.2733474|50.0217796,3.2781737|50.0293064,3.2712542|50.0319918,3.2580816|50.0243287,3.2582281|50.0281447,3.2451177|50.0307925,3.2443178|50.0278165,3.2343882|50.0326574,3.2289809|50.0288569,3.2237612|50.0260081,3.2230589|50.0269495,3.2210104|50.0212645,3.2133541|50.0165868,3.1977592|50.0150515,3.1977341|50.0147901,3.1965286|50.0171915,3.1961636|50.0130074,3.1845098|50.0113267,3.1729483|50.0177206,3.1705726|50.0210692,3.1670394|50.0182166,3.158297|50.0207314,3.150927|50.0179787,3.1485753|50.0184944,3.1470782|50.0273077,3.149845|50.024227,3.1340514|50.0244172,3.1236235|50.0270676,3.1244474|50.0260853,3.1184879|50.0344525,3.113806";

var filteredtextCoordinatesArray = coords.split('|');    

    centerLatArray = [];
    centerLngArray = [];


    for (i=0 ; i < filteredtextCoordinatesArray.length ; i++) {

      var centerCoords = filteredtextCoordinatesArray[i]; 
      var centerCoordsArray = centerCoords.split(',');

      if (isNaN(Number(centerCoordsArray[0]))) {      
      } else {
        centerLatArray.push(Number(centerCoordsArray[0]));
      }

      if (isNaN(Number(centerCoordsArray[1]))) {
      } else {
        centerLngArray.push(Number(centerCoordsArray[1]));
      }                    

    }

    var centerLatSum = centerLatArray.reduce(function(a, b) { return a + b; });
    var centerLngSum = centerLngArray.reduce(function(a, b) { return a + b; });

    var centerLat = centerLatSum / filteredtextCoordinatesArray.length ; 
    var centerLng = centerLngSum / filteredtextCoordinatesArray.length ;                                    

    console.log(centerLat);
    console.log(centerLng);

    var mapOpt = {      
    zoom:8,
    center: {lat: centerLat, lng: centerLng}      
    };

언급URL : https://stackoverflow.com/questions/15719951/auto-center-map-with-multiple-markers-in-google-maps-api-v3

반응형