Загрузка локального файла .kml с помощью Google Maps?

Я создал программу hello world для загрузки локального файла kml (заимствованного из документов google):

var ctaLayer = new google.maps.KmlLayer("http://localhost:8080/kml/cta.kml");

Это не работает (ничего не загружается).

Однако, когда я меняю эту строку на:

  var ctaLayer = new google.maps.KmlLayer("http://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml");

он загружается должным образом. Оба файла kml идентичны. Что мне нужно сделать, чтобы загрузить его при обслуживании? (Я пробовал как абсолютные, так и относительные пути, и я знаю, что пути, которые я использую, являются правильными...)

Также я добавил правильный тип mime в файл конфигурации apps apps:

<mime-mapping>
    <extension>kml</extension>
<mime-type>application/vnd.google-earth.kml+xml</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>kmz</extension>
    <mime-type>application/vnd.google-earth.kmz</mime-type>
</mime-mapping>

Но он все равно не загружается.

Я нашел это в google docs:

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

Итак, я предполагаю, что я пытаюсь сделать, не возможно без обслуживания kml из общедоступного url... если кто-то не может доказать иначе

Ответ 1

KML не может быть доступен, поскольку он находится на вашем локальном компьютере, и Google не может получить доступ к нему, поскольку он не знает, как добраться до localhost: 8080

Ответ 2

К сожалению, вы не можете использовать "localhost". У вас есть два варианта:

  • поместите kml в общедоступный домен. (если Google не может получить к нему доступ, он не будет работать)
  • Используйте geoxml3, который в основном делает то, что делает Google, но позволяет вам downlaod и размещать JS файл парсера самостоятельно. Это позволит вам загрузить KML LOCALHOST и проанализировать его для вас (объекты, доступные через JSON) (http://code.google.com/p/geoxml3/).

Вариант №1 не может быть вариантом для тех, кто работает над контрактами защиты и обрабатывает конфиденциальную информацию, поскольку kml отправляется в Google в фоновом режиме и отображается на карте.

Ответ 3

Этот веб-сайт display-kml.appspot.com требует, чтобы вы скопировали/вставили весь файл KML на веб-сайт. Кроме того, вы можете использовать Dropbox для размещения файла KML, используя вашу общую папку. В общедоступной папке Dropbox есть контекстное меню, вызываемое правой кнопкой мыши, которое позволяет скопировать URL-адрес.

Обновить:

Сайт appspot имеет нестабильную историю. По состоянию на январь 2019 года веб-сайт работает.

РЕКОМЕНДАЦИИ:
  1. http://display-kml.appspot.com/
  2. https://www.dropbox.com/

Ответ 4

Определенно, 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 самостоятельно.

ОБНОВИТЬ

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

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}
...