Покажем точки на карте

Задача: Необходимо показать несколько gps точек с базы на карте с возможностью измерения расстояния между ними.

Будем использовать apache, php, mysql для бекенда.

Схема таблицы, где будут храниться точки.

CREATE TABLE IF NOT EXISTS `gps_points` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `num` varchar(100) NOT NULL,
  `lat` double NOT NULL,
  `lon` double NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2919 ;

Пишем на PHP серверную часть, которая будет конвертировать все это в GeoJSON для этого мы воспользуемся вот этой библиотекой.

Переходим в папку с проектом и с помощью composer добавляем необходимы библиотеки. Для этого создаем файл composer.json в корне нашего проекта.

{
    "require": {
        "jmikola/geojson": "^1.0",
        "fxp/composer-asset-plugin": "~1.0",
        "bower-asset/leaflet-plugins": "1.3.11"
    }
}

Как вы заметили, кроме библиотеки geojson, я добавил еще composer-asset-plugin и leaflet-plugins. Первый — плагин к композеру, позволяющий заменить bower и npm. Второй — дополнительные плагины для leaflet (мы воспользуемся инструментом измерения расстояния)

ну и запускаем composer

# composer update

Все, необходимы библиотеки установлены. Теперь создадим файл points.php

<?php
require __DIR__ . '/vendor/autoload.php';

use GeoJson\Feature\Feature;
use GeoJson\Feature\FeatureCollection;
use GeoJson\Geometry\Point;

try {
    $db = new PDO('mysql:host=localhost;dbname=leps;charset=UTF8', 'root', '1');
} catch (PDOException $e) {
    echo $e->getMessage();
}

$res = $db->query("SELECT * FROM support");

$features = [];
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
    // Почему-то lat lon так (lon, lat) нужно писать. Методом тыка получил. Возможно что-то, где-то не так делаю.
    $point = new Point([floatval($row['lon']), floatval($row['lat'])]);
    $features[] = new Feature($point, ['popupContent'=>"[$row[id]] $row[num]<br>$row[name]"]);
}

$fc = new FeatureCollection($features);

echo json_encode($fc->jsonSerialize());

Теперь пишем клиентскую часть на базе  LeafletJS, для этого создадим index.html

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
    <link rel="stylesheet" href="vendor/bower-asset/leaflet-plugins/css/distance.css" />
    <link rel="stylesheet" href="http://leaflet.github.io/Leaflet.draw/leaflet.draw.css" />

    <style>
        html, body, #map {
            height:100%;
            width:100%;
            padding:0px;
            margin:0px;
        }
    </style>
</head>
<body>
    <div id="map"></div>
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
    <script src="http://leaflet.github.io/Leaflet.draw/leaflet.draw.js"></script>
    <script src="vendor/bower-asset/leaflet-plugins/control/Permalink.js"></script>
    <script src="vendor/bower-asset/leaflet-plugins/control/Permalink.Line.js"></script>
    <script src="vendor/bower-asset/leaflet-plugins/control/Distance.js"></script>
    <script>
        var map = L.map('map').setView([62.0128138, 129.6967919], 11);

        L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6IjZjNmRjNzk3ZmE2MTcwOTEwMGY0MzU3YjUzOWFmNWZhIn0.Y8bhBaUMqFiPrDRW9hieoQ', {
            maxZoom: 15,
            id: 'mapbox.streets'
        }).addTo(map);

        var d = new L.Control.Distance();
        map.addControl(d);
        map.addControl(new L.Control.Scale());
        map.addControl(new L.Control.Permalink({line: d.getLine(), useLocation: true}));

        //Загружаем точки
        $.getJSON("http://myserver.local/points.php",
                function(points) {
                    makeMarkers(points).addTo(map);
                }
        );

        function makeMarkers(points) {
            return L.geoJson(points, {
                pointToLayer: function (feature, latlng) {
                    return L.circleMarker(latlng, {
                        radius: 1,
                        fillColor: "#ff7800",
                        color: "red",
                        weight: 1,
                        opacity: 1,
                        fillOpacity: 0.8
                    });
                },
                onEachFeature: onEachFeature
            });
        }

        function onEachFeature(feature, layer) {
            var popupContent = "";

            if (feature.properties && feature.properties.popupContent) {
                popupContent += feature.properties.popupContent;
            }

            layer.bindPopup(popupContent);
        }

    </script>

</body>
</html>

Покажем точки на карте: 2 комментария

  1. Насчет
    // Почему-то lat lon так (lon, lat) нужно писать. Методом тыка получил. Возможно что-то, где-то не так делаю.

    Все дело в параметрах конструктора Point и традициях.
    Класс Point при создании экземпляра требует аргументы в порядке: абсцисса (X), ордината (Y). А в нашем мире Latitude — это широта (ордината), Longitude — долгота (абсцисса), но они традиционно читаются именно в таком порядке.
    Отсюда и инвертирование аргументов в конструкторе.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *