Моя задача — наложить пользовательские маркеры на изображение карты, которое я генерирую с помощью Google Static Maps API.
Проблема в том, что наложенные маркеры всегда немного смещены относительно своего исходного положения или, если быть точным, их положение выглядит как зеркальное отражение.
Я читал о том, как преобразовать сферические координаты в декартовы с помощью проекции Меркатора, но что-то не так, и я понятия не имею, что.
Это мой код PHP:
class GoogleMaps
{
const TILE_SIZE = 256;
const MAP_IMAGE_SIZE = 640;
private function getMercatorProjection($zoomLevel, $lat, $lng)
{
$pixelGlobeSize = self::TILE_SIZE * pow(2, $zoomLevel);
$xPixelsToDegreesRatio = $pixelGlobeSize / 360;
$yPixelsToRadiansRatio = $pixelGlobeSize / (2 * M_PI);
$halfPixelGlobeSize = $pixelGlobeSize / 2;
// get x value
$x = ($lng + 180) * ($pixelGlobeSize/360);
// convert from degrees to radians
$latRad = $lat * M_PI / 180;
// get y value
$mercN = log(tan((M_PI / 4) + ($latRad/2)));
$y = ($halfPixelGlobeSize) -($pixelGlobeSize * $mercN / (2 * M_PI));
return ['x' => $x, 'y' => $y];
}
/**
* @return string
*/
private function getStaticMapsUrl()
{
$url = 'http://maps.googleapis.com/maps/api/staticmap?key=' .
env('GOOGLE_MAPS_API_KEY');
$url .= sprintf('&path=color:%s|weight:%d|',
env('GM_PATH_COLOR'), env('GM_PATH_WEIGHT'));
foreach ($this->points as $point) {
$url .= $point->lat . ',' . $point->lng . '|';
}
$url = rtrim($url, '|');
$url .= '&scale=1&size=' . self::MAP_IMAGE_SIZE .
'x' . self::MAP_IMAGE_SIZE
$url .= '¢er=' . $this->getMapCenter(true);
$url .= '&zoom=' . ($this->getMapZoom());
return $url;
}
private function combineMapImageWithMarker($mapImage, $marker)
{
$resDir = realpath(__DIR__ . '/../../resources');
$markerImgRes = imagecreatefrompng("$resDir/icons/marker.png");
$mapImageRes = imagecreatefrompng($mapImage);
$zoom = $this->getMapZoom();
$mapCenter = $this->getMapCenter();
$markerXY = $this->getMercatorProjection($zoom, $marker->lat, $marker->lng);
$mapCenterXY = $this->getMercatorProjection($zoom, $mapCenter['lat'], $mapCenter['lng']);
$imageX = floor((self::MAP_IMAGE_SIZE / 2) + $mapCenterXY['x'] - $markerXY['x']);
$imageY = floor((self::MAP_IMAGE_SIZE / 2) + $mapCenterXY['y'] - $markerXY['y']);
imagecopy($mapImageRes, $markerImgRes,
$imageX, $imageY,
0, 0, $markerW, $markerH);
}
}
Вот как это выглядит на карте:
И вот что я получаю:
Буду благодарен за любую помощь.
Вы можете использовать (до 5 уникальных) пользовательские значки в маркерах.
IMO, наложение значков поверх уже отрисованной карты требует большой головной боли.
Других решений пока нет …