7 votos

¿Opción de exportar a KML con Leaflet?

Soy muy nuevo en esto de los SIG.

Tengo que integrar la opción de exportación a KML en uno de mis proyectos.

No pude ver esta opción al buscar en Google.

¿Existe la opción de hacer esto?

<!DOCTYPE html>
<html>
<head>
    <title>Leaflet.draw vector editing handlers</title>

    <script src="libs/leaflet-src.js"></script>
    <link rel="stylesheet" href="libs/leaflet.css" />

    <script src="../src/Leaflet.draw.js"></script>
    <link rel="stylesheet" href="../dist/leaflet.draw.css" />

    <link rel="stylesheet" href="../src/NavBar/Leaflet.NavBar.css" />

    <script src="../src/Toolbar.js"></script>
    <script src="../src/Tooltip.js"></script>

    <script src="../src/ext/GeometryUtil.js"></script>
    <script src="../src/ext/LatLngUtil.js"></script>
    <script src="../src/ext/LineUtil.Intersect.js"></script>
    <script src="../src/ext/Polygon.Intersect.js"></script>
    <script src="../src/ext/Polyline.Intersect.js"></script>

    <script src="../src/draw/DrawToolbar.js"></script>
    <script src="../src/draw/handler/Draw.Feature.js"></script>
    <script src="../src/draw/handler/Draw.SimpleShape.js"></script>
    <script src="../src/draw/handler/Draw.Polyline.js"></script>
    <script src="../src/draw/handler/Draw.Circle.js"></script>
    <script src="../src/draw/handler/Draw.Marker.js"></script>
    <script src="../src/draw/handler/Draw.Polygon.js"></script>
    <script src="../src/draw/handler/Draw.Rectangle.js"></script>

    <script src="../src/edit/EditToolbar.js"></script>
    <script src="../src/edit/handler/EditToolbar.Edit.js"></script>
    <script src="../src/edit/handler/EditToolbar.Delete.js"></script>

    <script src="../src/Control.Draw.js"></script>
    <script src="../src/NavBar/Leaflet.NavBar.js"></script>
    <script src="../src/edit/handler/Edit.Poly.js"></script>
    <script src="../src/edit/handler/Edit.SimpleShape.js"></script>
    <script src="../src/edit/handler/Edit.Circle.js"></script>
    <script src="../src/edit/handler/Edit.Rectangle.js"></script>
    <script src="../src/edit/handler/Edit.Marker.js"></script>
</head>
<body>
    <div id="map" style="width: 900px; height: 500px; border: 1px solid #ccc"></div>
    <button type="button" onclick="plotAccidents();">plot accidents</button><br/>
    <button type="button" onclick="clearAccidents();">clear accidents</button><br/>
    <button type="button" onclick="addWMS();">Add WMS</button><br/>
    <button type="button" onclick="panTo();">Pan To Address</button><br/>

WKT String : <span id="wktstring"></span>
    <script>
        var bounds;
        var plotbounds;
        var count=0;
        var checked =1;
        var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
            osm = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib});
            map = new L.Map('map', {layers: [osm], center: new L.LatLng(47.58, 29.22), zoom: 13}),
            drawnItems = L.featureGroup().addTo(map);

        var markers = new L.FeatureGroup(); 
        map.addControl(new L.Control.Draw({
            edit: { featureGroup: drawnItems }
        }));

        map.on('draw:created', function(event) {
            var layer = event.layer;

            drawnItems.addLayer(layer);
        });
        L.control.navbar().addTo(map);

        function plotAccidents()
        {
            populate();
            map.addLayer(markers);
        }
        function clearAccidents()
        {
            map.removeLayer(markers);
        }

        function getRandomLatLng(map) {

        //if(bounds==null)
        bounds = map.getBounds();
        if(count==0)
        {
        console.log(bounds);

        }
        //if(count==0)
        //{
            //console.log("southWest");
            //console.log(bounds.getSouthWest());
        //}
        southWest = bounds.getSouthWest();
        northEast = bounds.getNorthEast();
        lngSpan = northEast.lng - southWest.lng;
        latSpan = northEast.lat - southWest.lat;
    count++;
    return new L.LatLng(
    southWest.lat + latSpan * Math.random(),
    southWest.lng + lngSpan * Math.random());
    }

    function populate() {
    for (var i = 0; i < 10; i++) {
        var point = getRandomLatLng(map);

        if(plotbounds!=null && !plotbounds.contains(point))
        continue;
        var marker = L.marker(point);
        marker.bindPopup("<p>Accident details goes here</p>", {
            showOnMouseOver: true
        });
        markers.addLayer(marker);
    }
    return false;
}
function toWKT(layer) {
    var lng, lat, coords = [];

    if (layer instanceof L.Polygon || layer instanceof L.Polyline) {
        var latlngs = layer.getLatLngs();
        for (var i = 0; i < latlngs.length; i++) {
            latlngs[i]
            coords.push(latlngs[i].lng + " " + latlngs[i].lat);
            if (i === 0) {
                lng = latlngs[i].lng;
                lat = latlngs[i].lat;
            }
    };
        if (layer instanceof L.Polygon) {
            return "POLYGON((" + coords.join(",") + "," + lng + " " + lat + "))";
        } else if (layer instanceof L.Polyline) {
            return "LINESTRING(" + coords.join(",") + ")";
        }
    } else if (layer instanceof L.Marker) {
        return "POINT(" + layer.getLatLng().lng + " " + layer.getLatLng().lat + ")";
    }
}
var drawnItems = new L.LayerGroup();
map.on('draw:created', function (e) {
    var type = e.layerType; 

    plotbounds = e.layer.getBounds();
    console.log(plotbounds);
    var layer = e.layer;
    drawnItems.addLayer(layer);
    document.getElementById('wktstring').innerHTML=(toWKT(layer));
});

map.addLayer(drawnItems);
function addWMS()
{
    L.tileLayer.wms("http://sedac.ciesin.columbia.edu/geoserver/wms", {
    layers: 'gpw-v3:gpw-v3-population-density_2000',
    format: 'image/png',
    version: '1.1.0',
    transparent: true,
    attribution: "",
    tiled:true
}).addTo(map);
}
function panTo()
{
    map.panTo(new L.LatLng(40.737, -73.923));
}
</script>
</body>
</html>

0 votos

He actualizado la respuesta

8voto

Om Shankar Puntos 117

Indirectamente, utilizando tokml después de convertirlo en geojson:

<html>
<head>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
</head>
<body>
    <div id="map" style="width: 700px; height: 500px"></div>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <!-- include this from here: https://raw.githubusercontent.com/mapbox/tokml/master/tokml.js -->
    <script src="tokml.js"></script>

    <script>
        // set up a basic map and add a marker
        var map = L.map('map').setView([51.505, -0.09], 13);
        var marker = L.marker([51.5, -0.11]).addTo(map);

        // convert marker to geojson
        // layers also have a toGeoJSON function
        var json = marker.toGeoJSON();

        // then export to kml
        var kml = tokml(json);
    </script>
</body>

el kml que resulta de la operación anterior:

<?xml version="1.0" encoding="UTF-8"?>
  <kml xmlns="http://www.opengis.net/kml/2.2">
    <Document>
      <Placemark>
        <ExtendedData></ExtendedData>
        <Point>
          <coordinates>-0.11,51.5</coordinates>
        </Point>
      </Placemark>
    </Document>
</kml>

Actualización:

Si es drawnItems que desea convertir en kml, puede utilizar toGeoJSON en el featureGroup :

var json = drawnItems.toGeoJSON();
var kml = tokml(json);

Esto funciona en capas con geometrías mixtas (puntos, líneas, polígonos).

No sé dónde tiene más sentido que hagas esto en tu código. drawnItems se declara en el ámbito global, por lo que podría hacerlo en draw.on('created') o en una nueva función activada por un botón de exportación (por ejemplo).

0 votos

Gracias. Necesito convertir una capa que contiene múltiples formas.

0 votos

¿puede poner algún código en su pregunta? Al menos cómo estás creando los datos y añadiéndolos al mapa.

0 votos

He añadido el código. Pensé primero en convertir la capa a geojson. pero no podía n't encontrar ninguna opción. puede usted pls dar alguna sugerencia como ot proceder. Tengo escena la misma opción disponible en ArcGIS.

3voto

Estoy viendo el mismo problema. En primer lugar la conversión a geoJSON y luego KML. Este tokml parece prometedor y parece funcionar. El primer problema es geoJSON no reconoce los círculos, así que necesitaba una solución para eso - encontrado en otro hilo.

Así que lo que estoy haciendo.

Necesito una función para reemplazar las formas de círculo con polígonos calculados cuando se agregan. Entonces una función para generar geoJSON, ( i asignado a un botón ). El simplemente plantear el geoJSON tokml.
Esta es mi versión del proceso. Disparo shapes1 en un botón cuando he terminado $('#textareashowinggeojson').val(shapes1).select();

A partir de ahí puedes simplemente ejecutar tokml con ese textarea o simplemente con el valor devuelto por shapes1

    function createGeodesicPolygon(origin, radius, sides, rotation, projection) {

        var latlon = origin; //leaflet equivalent
        var angle;
        var new_lonlat, geom_point;
        var points = [];

        for (var i = 0; i < sides; i++) {
            angle = (i * 360 / sides) + rotation;
            new_lonlat = destinationVincenty(latlon, angle, radius); 
            geom_point = L.latLng(new_lonlat.lng, new_lonlat.lat); 

            points.push(geom_point); 
        }   

        return points; 
    };
    L.Util.VincentyConstants = {
        a: 6378137,
        b: 6356752.3142,
        f: 1/298.257223563  
    };  
    function destinationVincenty(lonlat, brng, dist) { //rewritten to work with leaflet

        var u = L.Util;
        var ct = u.VincentyConstants;
        var a = ct.a, b = ct.b, f = ct.f;
        var lon1 = lonlat.lng;
        var lat1 = lonlat.lat;
        var s = dist;
        var pi = Math.PI;
        var alpha1 = brng * pi/180 ; //converts brng degrees to radius
        var sinAlpha1 = Math.sin(alpha1);
        var cosAlpha1 = Math.cos(alpha1);
        var tanU1 = (1-f) * Math.tan( lat1 * pi/180 /* converts lat1 degrees to radius */ ); 
        var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
        var sigma1 = Math.atan2(tanU1, cosAlpha1);
        var sinAlpha = cosU1 * sinAlpha1;
        var cosSqAlpha = 1 - sinAlpha*sinAlpha;
        var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
        var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
        var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
        var sigma = s / (b*A), sigmaP = 2*Math.PI;
        while (Math.abs(sigma-sigmaP) > 1e-12) {
            var cos2SigmaM = Math.cos(2*sigma1 + sigma);
            var sinSigma = Math.sin(sigma);
            var cosSigma = Math.cos(sigma);
            var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
                B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
            sigmaP = sigma;
            sigma = s / (b*A) + deltaSigma;
        }
        var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
        var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
            (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
        var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
        var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
        var lam = lambda - (1-C) * f * sinAlpha *
            (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));  
        var revAz = Math.atan2(sinAlpha, -tmp);  // final bearing
        var lamFunc = lon1 + (lam * 180/pi); //converts lam radius to degrees
        var lat2a = lat2 * 180/pi; //converts lat2a radius to degrees

        return L.latLng(lamFunc, lat2a);

    };

    map.on('draw:created', function (e) {

        var type = e.layerType,
            layer = e.layer;

        if (type === 'circle') {

            var origin = layer.getLatLng(); //center of drawn circle
            var radius = layer.getRadius(); //radius of drawn circle
            var projection = L.CRS.EPSG4326;
            var polys = createGeodesicPolygon(origin, radius, 60, 0, projection); //these are the points that make up the circle
            var polygon = []; // store the geometry
            for (var i = 0; i < polys.length; i++) {
                var geometry = [polys[i].lat, polys[i].lng]; 
                polygon.push(geometry);
            }
            var cpolygon = L.polygon(polygon);
            drawnItems.addLayer(cpolygon);
        } else {
            //Just do as normal
            drawnItems.addLayer(layer);
        }
    });

    var getShapes1 = function(drawnItems) {
        var shapes1 = JSON.stringify(drawnItems.toGeoJSON());
        return shapes1;
    };

0voto

Rápidamente agarré tu y abofeteé algo. Parece que has redeclarado los drawnitems más adelante - no estoy seguro de por qué La función en la parte inferior del javascript debe obtener lo que necesita.

genKml()

    var bounds;
    var plotbounds;
    var count=0;
    var checked =1;
    var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        osm = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib});
        map = new L.Map('map', {layers: [osm], center: new L.LatLng(47.58, 29.22), zoom: 13}),
        drawnItems;

    var markers = new L.FeatureGroup(); 

    drawnItems = L.featureGroup().addTo(map);
    map.addControl(new L.Control.Draw({
        draw: {
            circle: true, 
            polygon: {allowIntersection: false}                    
        },
        edit: { featureGroup: drawnItems }
    }));

    map.on('draw:created', function (e) {

        var type = e.layerType,
            layer = e.layer;

        if (type === 'circle') {

            var origin = layer.getLatLng(); //center of drawn circle
            var radius = layer.getRadius(); //radius of drawn circle
            var projection = L.CRS.EPSG4326;
            var polys = createGeodesicPolygon(origin, radius, 60, 0, projection); //these are the points that make up the circle
            var polygon = []; // store the geometry
            for (var i = 0; i < polys.length; i++) {
                var geometry = [polys[i].lat, polys[i].lng]; 
                polygon.push(geometry);
            }
            var cpolygon = L.polygon(polygon);
            drawnItems.addLayer(cpolygon);
        } else {

            drawnItems.addLayer(layer);
        }
    });

    var getShapes = function(drawnItems) {
        var shapes = JSON.stringify(drawnItems.toGeoJSON());
        return shapes;
    };

    L.control.navbar().addTo(map);

    function plotAccidents()
    {
        populate();
        map.addLayer(markers);
    }
    function clearAccidents()
    {
        map.removeLayer(markers);
    }

    function getRandomLatLng(map) {

    //if(bounds==null)
    bounds = map.getBounds();
    if(count==0)
    {
    console.log(bounds);

    }
    //if(count==0)
    //{
        //console.log("southWest");
        //console.log(bounds.getSouthWest());
    //}
    southWest = bounds.getSouthWest();
    northEast = bounds.getNorthEast();
    lngSpan = northEast.lng - southWest.lng;
    latSpan = northEast.lat - southWest.lat;
count++;
return new L.LatLng(
southWest.lat + latSpan * Math.random(),
southWest.lng + lngSpan * Math.random());
}

function populate() {
for (var i = 0; i < 10; i++) {
    var point = getRandomLatLng(map);

    if(plotbounds!=null && !plotbounds.contains(point))
    continue;
    var marker = L.marker(point);
    marker.bindPopup("<p>Accident details goes here</p>", {
        showOnMouseOver: true
    });
    markers.addLayer(marker);
}
return false;

} function toWKT(layer) { var lng, lat, coords = [];

if (layer instanceof L.Polygon || layer instanceof L.Polyline) {
    var latlngs = layer.getLatLngs();
    for (var i = 0; i < latlngs.length; i++) {
        latlngs[i]
        coords.push(latlngs[i].lng + " " + latlngs[i].lat);
        if (i === 0) {
            lng = latlngs[i].lng;
            lat = latlngs[i].lat;
        }
};
    if (layer instanceof L.Polygon) {
        return "POLYGON((" + coords.join(",") + "," + lng + " " + lat + "))";
    } else if (layer instanceof L.Polyline) {
        return "LINESTRING(" + coords.join(",") + ")";
    }
} else if (layer instanceof L.Marker) {
    return "POINT(" + layer.getLatLng().lng + " " + layer.getLatLng().lat + ")";
}

}

    function createGeodesicPolygon(origin, radius, sides, rotation, projection) {

        var latlon = origin; //leaflet equivalent
        var angle;
        var new_lonlat, geom_point;
        var points = [];

        for (var i = 0; i < sides; i++) {
            angle = (i * 360 / sides) + rotation;
            new_lonlat = destinationVincenty(latlon, angle, radius); 
            geom_point = L.latLng(new_lonlat.lng, new_lonlat.lat); 

            points.push(geom_point); 
        }   

        return points; 
    };
    L.Util.VincentyConstants = {
        a: 6378137,
        b: 6356752.3142,
        f: 1/298.257223563  
    };  
    function destinationVincenty(lonlat, brng, dist) { //rewritten to work with leaflet

        var u = L.Util;
        var ct = u.VincentyConstants;
        var a = ct.a, b = ct.b, f = ct.f;
        var lon1 = lonlat.lng;
        var lat1 = lonlat.lat;
        var s = dist;
        var pi = Math.PI;
        var alpha1 = brng * pi/180 ; //converts brng degrees to radius
        var sinAlpha1 = Math.sin(alpha1);
        var cosAlpha1 = Math.cos(alpha1);
        var tanU1 = (1-f) * Math.tan( lat1 * pi/180 /* converts lat1 degrees to radius */ ); 
        var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
        var sigma1 = Math.atan2(tanU1, cosAlpha1);
        var sinAlpha = cosU1 * sinAlpha1;
        var cosSqAlpha = 1 - sinAlpha*sinAlpha;
        var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
        var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
        var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
        var sigma = s / (b*A), sigmaP = 2*Math.PI;
        while (Math.abs(sigma-sigmaP) > 1e-12) {
            var cos2SigmaM = Math.cos(2*sigma1 + sigma);
            var sinSigma = Math.sin(sigma);
            var cosSigma = Math.cos(sigma);
            var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
                B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
            sigmaP = sigma;
            sigma = s / (b*A) + deltaSigma;
        }
        var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
        var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
            (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
        var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
        var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
        var lam = lambda - (1-C) * f * sinAlpha *
            (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));  
        var revAz = Math.atan2(sinAlpha, -tmp);  // final bearing
        var lamFunc = lon1 + (lam * 180/pi); //converts lam radius to degrees
        var lat2a = lat2 * 180/pi; //converts lat2a radius to degrees

        return L.latLng(lamFunc, lat2a);

    };

var drawnItems = new L.LayerGroup(); map.on('draw:created', function (e) { var type = e.layerType;

plotbounds = e.layer.getBounds();
console.log(plotbounds);
var layer = e.layer;
drawnItems.addLayer(layer);
document.getElementById('wktstring').innerHTML=(toWKT(layer));

});

map.addLayer(drawnItems); función addWMS() { L.tileLayer.wms(" http://sedac.ciesin.columbia.edu/geoserver/wms ", { capas: 'gpw-v3:gpw-v3-population-density_2000', formato: 'image/png', versión: '1.1.0', transparente: true, atribución: "", mosaico:true }).addTo(map); } function panTo() { map.panTo(new L.LatLng(40.737, -73.923)); }

function genKml() { var myJSONdata = getShapes(drawnItems); run(JSON.parse(myJSONdata)); };

<script src='../src/site/site.js'></script>

0voto

Además, simplemente incluya el archivo tokml.js Esto generará el kml. JSON.parse es necesario para que tokml funcione. las opciones de tokml documentname documentdescription simplestyle son opcionales

var kshapes = JSON.stringify(drawnItems.toGeoJSON());
    var kmlDoc = tokml(JSON.parse(kshapes), {
        documentName: 'My Polygons',
        documentDescription: 'Some stuff I drew', 
        simplestyle: true
    });

A continuación, voy a enviar los resultados en un formulario a otra página para generar un archivo para descargar.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X