Рисование круга Google Static Maps - PullRequest
16 голосов
/ 06 сентября 2011

У меня есть Google Maps Circle, нарисованный на v3 api.Когда пользователь нанесет на него окружность (или многоугольник, если он выберет), он может сохранить данные на сервере.Если пользователь выбрал радиальный поиск, координаты центра и радиус в футах сохраняются в базе данных.Это означает, что когда пользователь перезагружает свой поиск, он может снова пройти круг (как показано ниже).

Example of load

У меня, однако, одна проблема, которая возникает, когда пользовательвыбирает, какой поиск они хотели бы использовать.Он прекрасно загружает многоугольник, если они нарисовали многоугольник, и если это круг, он тянет через маркер в центре.Однако в статических картах мне нужна функция для рисования круга.

Ответы [ 5 ]

26 голосов
/ 23 мая 2012

Немного опоздал в игре, но ничего, что я нашел, не решило мою проблему (только серверный php, без javascript). В конце концов я попал туда и подробно описал свой метод здесь: http://jomacinc.com/map-radius/, а короткая версия ниже.

Эта функция PHP будет возвращать закодированную строку ломаной линии точек широты и долготы в круге вокруг указанной точки и в указанном радиусе. Для этой функции требуется класс полилинии PHP Габриэля Свеннерберга, доступный здесь (http://www.svennerberg.com/examples/polylines/PolylineEncoder.php.txt).

function GMapCircle($Lat,$Lng,$Rad,$Detail=8){
 $R    = 6371;

 $pi   = pi();

 $Lat  = ($Lat * $pi) / 180;
 $Lng  = ($Lng * $pi) / 180;
 $d    = $Rad / $R;

 $points = array();
 $i = 0;

 for($i = 0; $i <= 360; $i+=$Detail):
   $brng = $i * $pi / 180;

   $pLat = asin(sin($Lat)*cos($d) + cos($Lat)*sin($d)*cos($brng));
   $pLng = (($Lng + atan2(sin($brng)*sin($d)*cos($Lat), cos($d)-sin($Lat)*sin($pLat))) * 180) / $pi;
   $pLat = ($pLat * 180) /$pi;

   $points[] = array($pLat,$pLng);
 endfor;

 require_once('PolylineEncoder.php');
 $PolyEnc   = new PolylineEncoder($points);
 $EncString = $PolyEnc->dpEncode();

 return $EncString['Points'];
}

Теперь вы можете использовать вышеуказанную функцию для создания статической карты.

/* set some options */
$MapLat    = '-42.88188'; // latitude for map and circle center
$MapLng    = '147.32427'; // longitude as above
$MapRadius = 100;         // the radius of our circle (in Kilometres)
$MapFill   = 'E85F0E';    // fill colour of our circle
$MapBorder = '91A93A';    // border colour of our circle
$MapWidth  = 640;         // map image width (max 640px)
$MapHeight = 480;         // map image height (max 640px)

/* create our encoded polyline string */
$EncString = GMapCircle($MapLat,$MapLng, $MapRadius);

/* put together the static map URL */
$MapAPI = 'http://maps.google.com.au/maps/api/staticmap?';
$MapURL = $MapAPI.'center='.$MapLat.','.$MapLng.'&size='.$MapWidth.'x'.$MapHeight.'&maptype=roadmap&path=fillcolor:0x'.$MapFill.'33%7Ccolor:0x'.$MapBorder.'00%7Cenc:'.$EncString.'&sensor=false';

/* output an image tag with our map as the source */
echo '<img src="'.$MapURL.'" />'
15 голосов
/ 26 февраля 2016
function GMapCircle(lat,lng,rad,detail=8){

var uri = 'https://maps.googleapis.com/maps/api/staticmap?';
var staticMapSrc = 'center=' + lat + ',' + lng;
staticMapSrc += '&size=100x100';
staticMapSrc += '&path=color:0xff0000ff:weight:1';

var r    = 6371;

var pi   = Math.PI;

var _lat  = (lat * pi) / 180;
var _lng  = (lng * pi) / 180;
var d    = (rad/1000) / r;

var i = 0;

for(i = 0; i <= 360; i+=detail) {
    var brng = i * pi / 180;

    var pLat = Math.asin(Math.sin(_lat) * Math.cos(d) + Math.cos(_lat) * Math.sin(d) * Math.cos(brng));
    var pLng = ((_lng + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(_lat), Math.cos(d) - Math.sin(_lat) * Math.sin(pLat))) * 180) / pi;
    pLat = (pLat * 180) / pi;

   staticMapSrc += "|" + pLat + "," + pLng;
}

return uri + encodeURI(staticMapSrc);}

Версия Javascript

3 голосов
/ 29 июня 2016

Основано на ответе от Jomac . Вот версия того же кода на Java / Android.

Используется класс PolyUtil из Утилита Google Maps Android API Library для кодирования пути.

import android.location.Location;

import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.PolyUtil;

import java.util.ArrayList;

public class GoogleStaticMapsAPIServices
{
    private static final double EARTH_RADIUS_KM = 6371;

    private static String GOOGLE_STATIC_MAPS_API_KEY = "XXXXXXXXXXXXX";

    public static String getStaticMapURL(Location location, int radiusMeters)
    {
        String pathString = "";
        if (radiusMeters > 0)
        {
            // Add radius path
            ArrayList<LatLng> circlePoints = getCircleAsPolyline(location, radiusMeters);

            if (circlePoints.size() > 0)
            {
                String encodedPathLocations = PolyUtil.encode(circlePoints);
                pathString = "&path=color:0x0000ffff%7Cweight:1%7Cfillcolor:0x0000ff80%7Cenc:" + encodedPathLocations;
            }
        }

        String staticMapURL = "https://maps.googleapis.com/maps/api/staticmap?size=640x320&markers=color:red%7C" +
                location.getLatitude() + "," + location.getLongitude() +
                pathString +
                "&key=" + GOOGLE_STATIC_MAPS_API_KEY;

        return staticMapURL;
    }

    private static ArrayList<LatLng> getCircleAsPolyline(Location center, int radiusMeters)
    {
        ArrayList<LatLng> path = new ArrayList<>();

        double latitudeRadians = center.getLatitude() * Math.PI / 180.0;
        double longitudeRadians = center.getLongitude() * Math.PI / 180.0;
        double radiusRadians = radiusMeters / 1000.0 / EARTH_RADIUS_KM;

        double calcLatPrefix = Math.sin(latitudeRadians) * Math.cos(radiusRadians);
        double calcLatSuffix = Math.cos(latitudeRadians) * Math.sin(radiusRadians);

        for (int angle = 0; angle < 361; angle += 10)
        {
            double angleRadians = angle * Math.PI / 180.0;

            double latitude = Math.asin(calcLatPrefix + calcLatSuffix * Math.cos(angleRadians));
            double longitude = ((longitudeRadians + Math.atan2(Math.sin(angleRadians) * Math.sin(radiusRadians) * Math.cos(latitudeRadians), Math.cos(radiusRadians) - Math.sin(latitudeRadians) * Math.sin(latitude))) * 180) / Math.PI;
            latitude = latitude * 180.0 / Math.PI;

            path.add(new LatLng(latitude, longitude));
        }

        return path;
    }
}
2 голосов
/ 06 сентября 2011

Я думаю, что невозможно нарисовать круг на статической карте Google. Вам нужно будет округлить окружность полилинией (лучше всего в кодированном формате ). Это уже упоминалось в Stackoverflow , и это демонстрируется, например, Бесплатные инструменты для карт .

0 голосов
/ 08 марта 2018

Обмен моей версией C #

private string GMapCircle(double lat, double lng, double rad, int detail = 8)
{
    const string uri = "https://maps.googleapis.com/maps/api/staticmap?";
    var staticMapSrc = "center=" + lat + "," + lng;
    staticMapSrc += "&zoom=16";
    staticMapSrc += "&maptype=satellite";
    staticMapSrc += "&key=[YOURKEYHERE]";
    staticMapSrc += "&size=640x426";
    staticMapSrc += "&path=color:0xff0000ff:weight:1";

    const int r = 6371;
    const double pi = Math.PI;

    var latAux = (lat * pi) / 180;
    var longAux = (lng * pi) / 180;
    var d = (rad / 1000) / r;

    var i = 0;

    if (rad > 0)
    {
        for (i = 0; i <= 360; i += detail)
        {
            var brng = i * pi / 180;

            var pLat = Math.Asin(Math.Sin(latAux) * Math.Cos(d) + Math.Cos(latAux) * Math.Sin(d) * Math.Cos(brng));
            var pLng = ((longAux + Math.Atan2(Math.Sin(brng) * Math.Sin(d) * Math.Cos(latAux), Math.Cos(d) - Math.Sin(latAux) * Math.Sin(pLat))) * 180) / pi;
            pLat = (pLat * 180) / pi;

            staticMapSrc += "|" + pLat + "," + pLng;
        }
    }
    else
    {
        //TODO - Add marker
    }

    return uri + staticMapSrc;
}
...