Google Maps API и KML-файл Варианты разработки LocalHost - PullRequest
14 голосов
/ 23 мая 2011

API библиотеки Google Maps JavaScript версии 3 четко объясняет :

API Карт Google поддерживает форматы данных KML и GeoRSS для отображения географической информации.Эти форматы данных отображаются на карте с помощью объекта KmlLayer, конструктор которого принимает URL-адрес общедоступного файла KML или GeoRSS.

даже несколько вопросов о переполнении стека о том, как загружать локальные данные:

В некоторых ответах были указаны сторонние библиотеки, которые могут анализировать KML локально без необходимости публикации файла:

И хотя эти решения хороши, если вам нужно сохранить вашиданные приватные, я просто хочу сделать разработку проще.При локальном запуске я, очевидно, не могу разобрать свой KML и поэтому теряю функциональность, которую пытаюсь проверитьЯ опубликовал один общий файл KML на общедоступном сайте, но затем мне нужно иметь другой код разработки, чтобы отображать одну вещь вместо другой при реальной работе.

Какие у меня есть варианты для локальной разработки?сделать то, что было бы общедоступным динамически генерируемым файлам KML?

Ответы [ 2 ]

11 голосов
/ 24 мая 2011

Похоже, вы довольно хорошо обрисовали варианты:

Если вы хотите работать с локальными данными, без привлечения общедоступного веб-сервера , вам потребуется использовать подход на основе javascript для анализа KML и загрузки его на карту. Хотя это не будет полностью повторять функциональность Google, вероятно, этого будет достаточно для первоначальной разработки, если вы заботитесь только о отображении функций KML. В этом случае я бы, вероятно, настроил класс-заглушку, например:

    // I'll assume you have a global namespace called MyProject
    MyProject.LOCAL_KML = true;

    MyProject.KmlLayer = function(url) {
        // parse the KML, maybe caching an array of markers or polygons,
        // using one of the libraries you list in your question
    };

    // now stub out the methods you care about, based on
    // http://code.google.com/apis/maps/documentation/javascript/reference.html#KmlLayer
    MyProject.KmlLayer.prototype.setMap = function(map) {
        // add the markers and polygons to the map, or remove them if !map
    }
    // etc

Теперь либо вставьте переключатель в код, либо оставьте комментарий / раскомментируйте, либо используйте сценарий сборки для переключения, либо используйте текущий процесс для переключения между dev и рабочим кодом:

    var kmlPath = "/my.kml";
    var kmlLayer =  MyProject.LOCAL_KML ?
        new MyProject.KmlLayer(MyProject.LOCAL_KML_HOST + kmlPath) :
        new google.maps.KmlLayer(MyProject.PRODUCTION_KML_HOST + kmlPath);
    kmlLayer.setMap(myMap);

Если, с другой стороны, вам нужны все функции в Google KmlLayer, или вы хотите убедиться, что все работает с настройкой производства, или вы не хотите беспокоиться Если вы отключите функции, предоставляемые Google, вам нужно будет загрузить их на общедоступный сервер, чтобы Google мог выполнять обработку на стороне сервера.

Помимо очевидных опций (FTP, сценарий командной строки для загрузки нового KML-файла и т. Д.), Для большинства из которых требуется выполнить какие-либо действия вручную перед загрузкой страницы карты, вы можете рассмотреть возможность встраивания обновления в страница, которую вы загружаете. В зависимости от используемой платформы, это может быть проще сделать на серверной или интерфейсной части; ключом будет иметь скрипт на вашем общедоступном сервере, который позволит обновлять KML:

  1. Получить строку KML из запроса. ПОЧТА
  2. Проверка строки KML (просто чтобы вы не открывали свой сервер для атак)
  3. Запись в один файл, например, "My.kml"

Затем при просмотре страницы карты обновите удаленный KML на основе данных из localhost. Вот версия на стороне клиента, использующая jQuery:

// again, you'd probably have a way to kill this block in production
if (MyProject.UPDATE_KML_FROM_LOCALHOST) {
    // get localhost KML
    $.get(MyProject.LOCAL_KML_HOST + kmlPath, function(data) {
        // now post it to the remote server
        $.post(
            MyProject.DEV_KML_HOST + '/update_kml.php', 
            { kml: data }, 
            function() {
                // after the post completes, get the KML layer from Google
                var kmlLayer new google.maps.KmlLayer(MyProject.DEV_KML_HOST + kmlPath);
                kmlLayer.setMap(myMap);
            }
        );
    })
}

По общему признанию, здесь есть много обходов (страница -> локальный хост, страница -> удаленный сервер, Google -> удаленный сервер, Google -> страница), так что это будет медленно . Но это позволит вам правильно отображать в коде Google динамические данные KML, созданные на локальном хосте, без необходимости выполнять отдельный шаг вручную при каждой перезагрузке страницы.

0 голосов
/ 07 ноября 2018

Определенно, Google Maps KmlLayer предназначен для того, чтобы вы отправляли им свои данные. https://developers.google.com/maps/documentation/javascript/kml

Посмотрите следующий журнал.

//console
var src = 'https://developers.google.com/maps/documentation/javascript/examples/kml/westcampus.kml';

var kmlLayer = new google.maps.KmlLayer(src, {
  suppressInfoWindows: true,
  preserveViewport: false,
  map: your_gmap_object
});

Создание Маркер, Полигон , все они Разбор и рендеринг на стороне браузера .

Как видно из следующего сетевого журнала, Класс KmlLayer отправляет исходный URL на сервер Google , чтобы проанализировать его и (сделать что-то в их конце) и отправить проанализированный результат обратно в ваш браузер для рендеринга.

//REQUEST from browser

https://maps.googleapis.com/maps/api/js/KmlOverlayService.GetOverlays?1shttps%3A%2F%2Fdevelopers.google.com%2Fmaps%2Fdocumentation%2Fjavascript%2Fexamples%2Fkml%2Fwestcampus.kml&callback=_xdc_._lidt3k&key=AIzaSyBeLTP20qMgxsQFz1mwLlzNuhrS5xD_a_U&token=103685

//RESPONSE from google server

/**/_xdc_._lidt3k && _xdc_._lidt3k( [0,"kml:cXOw0bjKUSmlnTN2l67v0Sai6WfXhSSWuyNaDD0mAzh6xfi2fYnBo78Y2Eg","|ks:;dc:tg;ts:51385071|kv:3|api:3",...
["KmlFile"],[[37.423017,-122.0927],[37.424194,-122.091498]],[["g74cf1503d602f2e5"],["g58e8cf8fd6da8d29"],["ge39d22e72437b02e"]],1,[["client","2"]],-21505,[["ks",";dc:tg;ts:51385071"],["kv","3"],["api","3"]]] )

Как упомянуто выше @capdragon, было бы лучше проанализировать KML самостоятельно .

UPDATE

Вот компактный код парсера KML. Это только для маркера google.maps и полигона.

HTML

<input type='file' accept=".kml,.kmz" onchange="fileChanged()">

скрипт, я использовал машинопись, но она очень похожа на javascript

  file: any
  fileChanged(e) {
    this.file = e.target.files[0]
    this.parseDocument(this.file)
  }
  parseDocument(file) {
    let fileReader = new FileReader()
    fileReader.onload = async (e: any) => {
      let result = await this.extractGoogleCoords(e.target.result)

      //CREATE MARKER OR POLYGON WITH result here
      console.log(result)

    }
    fileReader.readAsText(file)
  }

  async extractGoogleCoords(plainText) {
    let parser = new DOMParser()
    let xmlDoc = parser.parseFromString(plainText, "text/xml")
    let googlePolygons = []
    let googleMarkers = []

    if (xmlDoc.documentElement.nodeName == "kml") {

      for (const item of xmlDoc.getElementsByTagName('Placemark') as any) {
        let placeMarkName = item.getElementsByTagName('name')[0].childNodes[0].nodeValue.trim()
        let polygons = item.getElementsByTagName('Polygon')
        let markers = item.getElementsByTagName('Point')

        /** POLYGONS PARSE **/        
        for (const polygon of polygons) {
          let coords = polygon.getElementsByTagName('coordinates')[0].childNodes[0].nodeValue.trim()
          let points = coords.split(" ")

          let googlePolygonsPaths = []
          for (const point of points) {
            let coord = point.split(",")
            googlePolygonsPaths.push({ lat: +coord[1], lng: +coord[0] })
          }
          googlePolygons.push(googlePolygonsPaths)
        }

        /** MARKER PARSE **/    
        for (const marker of markers) {
          var coords = marker.getElementsByTagName('coordinates')[0].childNodes[0].nodeValue.trim()
          let coord = coords.split(",")
          googleMarkers.push({ lat: +coord[1], lng: +coord[0] })
        }
      }
    } else {
      throw "error while parsing"
    }

    return { markers: googleMarkers, polygons: googlePolygons }

  }

выход

markers: Array(3)
0: {lat: 37.42390182131783, lng: -122.0914977709329}
...

polygons: Array(1)
0: Array(88)
0: {lat: -37.79825999283025, lng: 144.9165994157198}
...
...