|
@@ -1,5 +1,16 @@
|
|
|
{% extends 'SonataAdminBundle:CRUD:base_list.html.twig' %}
|
|
|
|
|
|
+{% block stylesheets %}
|
|
|
+{{ parent() }}
|
|
|
+<style>
|
|
|
+.no_checkbox>i.jstree-checkbox
|
|
|
+{
|
|
|
+ display:none
|
|
|
+}
|
|
|
+</style>
|
|
|
+<link rel="stylesheet" href="/css/tree/proton/style.css" />
|
|
|
+{% endblock %}
|
|
|
+
|
|
|
{% block actions %}
|
|
|
{% endblock %}
|
|
|
|
|
@@ -7,98 +18,201 @@
|
|
|
{#{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': sonata_admin.adminPool.getTemplate('tab_menu_template')}, 'twig') }}#}
|
|
|
{% endblock %}
|
|
|
|
|
|
-{% block list_table %}
|
|
|
+{% block list_filters_actions %}
|
|
|
+{% endblock %}
|
|
|
|
|
|
-<div id="popups" style="display:none">
|
|
|
- {% if layers|length > 0 %}
|
|
|
- {% for layer in layers %}
|
|
|
- {% set vectors = layer['vectors'] %}
|
|
|
- {% if vectors|length > 0 %}
|
|
|
- {% for vector in vectors %}
|
|
|
- <div id="desc_vector_{{vector.getId()}}">{{vector.getDescription()|raw}}</div>
|
|
|
- {% endfor %}
|
|
|
- {% endif %}
|
|
|
- {% endfor %}
|
|
|
- {% endif %}
|
|
|
-</div>
|
|
|
+{% block list_filters %}
|
|
|
+{% endblock %}
|
|
|
+
|
|
|
+{% block list_table %}
|
|
|
|
|
|
{% include 'LeafletBundle:Leaflet:resources.html.twig' %}
|
|
|
|
|
|
<script type="text/javascript">
|
|
|
window.SONATA_CONFIG.USE_ICHECK = false;
|
|
|
+ window.currentLayer = null; // Almacena el ID del layer actualmente seleccionado.
|
|
|
|
|
|
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
|
osmAttrib = '© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
|
osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib }),
|
|
|
map = new L.Map('map', { center: new L.LatLng({{map['lat']}}, {{map['lng']}}), zoom: {{map['zoom']}} });
|
|
|
-
|
|
|
+
|
|
|
var controlLayers = L.control.layers({
|
|
|
- 'osm': osm.addTo(map),
|
|
|
- "google": L.tileLayer('http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}', {
|
|
|
+ 'OSM': osm.addTo(map),
|
|
|
+ "Google": L.tileLayer('http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}', {
|
|
|
attribution: 'google'
|
|
|
})
|
|
|
}, {}, { position: 'topleft', collapsed: false });
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
addLayersMap();
|
|
|
|
|
|
controlLayers.addTo(map);
|
|
|
|
|
|
-
|
|
|
+ // Agregar Clase para dibujo de vectores
|
|
|
+ window.drawControl = new L.Control.Draw();
|
|
|
+
|
|
|
+ map.on(L.Draw.Event.CREATED, function (event) {
|
|
|
+ /* Se dispara tras creación de vector */
|
|
|
+ var uuid = guid();
|
|
|
+ var layer = event.layer;
|
|
|
+ var currentLayer = layers[window.currentLayer];
|
|
|
+
|
|
|
+ layer.layerType = event.layerType;
|
|
|
+ layer.layerClass = "vector";
|
|
|
+ currentLayer.addLayer(layer);
|
|
|
+
|
|
|
+ currentLayer.eachLayer(function(layer) {
|
|
|
+ if (typeof layer._uuid === 'undefined') {
|
|
|
+ layer._uuid = uuid + "_" + layer._leaflet_id;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ saveData();
|
|
|
+ refresh();
|
|
|
+ });
|
|
|
+
|
|
|
+ map.on(L.Draw.Event.DELETED, function (event) {
|
|
|
+ /* Se dispara tras borrado de vector */
|
|
|
+ var layers = event.layers;
|
|
|
+ var deleteLayers = new Array();
|
|
|
+ layers.eachLayer(function(layer) {
|
|
|
+ deleteLayers.push(layer._uuid);
|
|
|
+ });
|
|
|
+
|
|
|
+ sendData = {'layerId' : layerId, 'vectors' : deleteLayers};
|
|
|
+ var json = JSON.stringify(sendData);
|
|
|
+
|
|
|
+ saveData();
|
|
|
+ refresh()
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+function saveData() {
|
|
|
+ /*
|
|
|
+ * Guarda todos los layers presentes en window.layers
|
|
|
+ * y a sus correspondientes vectores
|
|
|
+ */
|
|
|
+ $.each(window.layers, function(id, myLayer) {
|
|
|
+ var vectorData = new Array();
|
|
|
+ if (myLayer) {
|
|
|
+ myLayer.eachLayer(function(layer) {
|
|
|
+
|
|
|
+ if(layer.layerType == "marker") {
|
|
|
+ data = [layer._latlng];
|
|
|
+ } else if (layer.layerType == "circle") {
|
|
|
+ data = [layer._latlng, layer._mRadius];
|
|
|
+ } else if (layer.layerType == "polyline") {
|
|
|
+ data = [layer._latlngs];
|
|
|
+ } else {
|
|
|
+ data = [layer._latlngs[0]];
|
|
|
+ }
|
|
|
+
|
|
|
+ object = {'_uuid': layer._uuid, 'layerType': layer.layerType, 'data': data, 'layerId': layer._id};
|
|
|
+ vectorData.push(object);
|
|
|
+ });
|
|
|
+
|
|
|
+ sendData = {'layerId' : id, 'vectors' : vectorData};
|
|
|
+ var json = JSON.stringify(sendData);
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ type: "POST",
|
|
|
+ url: "{{ path('admin_map_vector_create_ajax') }}",
|
|
|
+ data: json,
|
|
|
+ contentType: "application/json; charset=utf-8",
|
|
|
+ dataType: "json",
|
|
|
+ error: function(msg) {
|
|
|
+ console.log(msg.msg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
|
|
|
function addLayersMap() {
|
|
|
+ /*
|
|
|
+ * Obtiene todos los layers y vectores de un mapa.
|
|
|
+ * Luego los agrega al control Leaflet
|
|
|
+ */
|
|
|
+ window.layers = new Array();
|
|
|
+
|
|
|
+ var url = window.location.pathname;
|
|
|
+ var id = url.substring(url.lastIndexOf('/') + 1);
|
|
|
+ var mapData = getData('maps', id );
|
|
|
+
|
|
|
+ for(var i=0; i < mapData.layers.length; i++) {
|
|
|
+
|
|
|
+ var layer = mapData.layers[i];
|
|
|
+ newLayer = L.featureGroup();
|
|
|
+
|
|
|
+ for(var j=0; j < layer.vectors.length; j++ ) {
|
|
|
|
|
|
- {% if layers|length > 0 %}
|
|
|
- {% for layer in layers %}
|
|
|
- {% set vectors = layer['vectors'] %}
|
|
|
- {% set layerName = layer['name'] %}
|
|
|
- {% if vectors|length > 0 %}
|
|
|
-
|
|
|
- newLayer = L.featureGroup();
|
|
|
-
|
|
|
- {% for vector in vectors %}
|
|
|
- _id = {{vector.getId()}};
|
|
|
- name = "{{vector.getName()}}";
|
|
|
- type = "{{vector.getType()}}"
|
|
|
- _uuid = "{{vector.getUuid()}}"
|
|
|
- data = JSON.parse('{{vector.getData()}}'.replace(/"/g,'"'));
|
|
|
-
|
|
|
- if(type == "marker") {
|
|
|
- style = JSON.parse('{{vector.getInlineStyle()}}'.replace(/"/g,'"'));
|
|
|
- if (typeof style.icon !== 'undefined') {
|
|
|
- icon = style.icon;
|
|
|
- } else {
|
|
|
- icon = "miniBubbleBlueIcon";
|
|
|
+ var vector = layer.vectors[j];
|
|
|
+
|
|
|
+ _id = vector.id;
|
|
|
+ name = vector.name;
|
|
|
+ type = vector.type;
|
|
|
+ _uuid = vector.uuid;
|
|
|
+ data = JSON.parse(vector.data);
|
|
|
+ style = JSON.parse(vector.style);
|
|
|
+
|
|
|
+ if(type == "marker") {
|
|
|
+ if (typeof style.icon !== 'undefined') {
|
|
|
+ icon = style.icon;
|
|
|
+ } else {
|
|
|
+ icon = "miniBubbleBlueIcon";
|
|
|
+ }
|
|
|
+ object = new L.marker([data[0]['lat'], data[0]['lng']],{icon: eval(icon)});
|
|
|
+ } else if (type == "circle") {
|
|
|
+ object = new L.circle([data[0]['lat'], data[0]['lng']], data[1], style);
|
|
|
+ } else if (type == "polyline") {
|
|
|
+ object = new L.Polyline(data[0], style);
|
|
|
+ } else if (type == "rectangle"){
|
|
|
+ object = new L.Rectangle(data[0], style);
|
|
|
+ } else {
|
|
|
+ object = new L.Polygon(data[0], style);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ object._id = _id;
|
|
|
+ object.name = name;
|
|
|
+ object._uuid = _uuid;
|
|
|
+ object.layerType = type;
|
|
|
+ object.layerClass = "vector";
|
|
|
+ var desc = $("#desc_vector_" + vector.id).html();
|
|
|
+
|
|
|
+ object.on("click", function (e) {
|
|
|
+ var layer = e.target
|
|
|
+
|
|
|
+ if (layer.class = 'vector') {
|
|
|
+ // Deseleccionar todos los elementos.
|
|
|
+ $('#jstree').jstree('deselect_all');
|
|
|
+ $('#overlay_tree').jstree('deselect_all');
|
|
|
+
|
|
|
+ for (key in layer._eventParents) {
|
|
|
+ var leafletId = key; // Debería iterar una sola vez
|
|
|
+ }
|
|
|
+
|
|
|
+ // Seleccionar elementos:
|
|
|
+ for (key in window.layers) {
|
|
|
+ if (window.layers[key]._leaflet_id == leafletId) {
|
|
|
+ $('#jstree').jstree('select_node', key);
|
|
|
}
|
|
|
- object = new L.marker([data[0]['lat'], data[0]['lng']],{icon: eval(icon)});
|
|
|
- } else if (type == "circle") {
|
|
|
- object = new L.circle([data[0]['lat'], data[0]['lng']], data[1],{{vector.getInlineStyle()|raw}});
|
|
|
- } else if (type == "polyline") {
|
|
|
- object = new L.Polyline({{vector.getPolylinePoints()}},{{vector.getInlineStyle()|raw}});
|
|
|
- } else if (type == "rectangle"){
|
|
|
- object = new L.Rectangle({{vector.getPolylinePoints()}},{{vector.getInlineStyle()|raw}});
|
|
|
- } else {
|
|
|
- object = new L.Polygon({{vector.getPolylinePoints()}},{{vector.getInlineStyle()|raw}});
|
|
|
}
|
|
|
|
|
|
- object._id = _id;
|
|
|
- object.name = name;
|
|
|
- object._uuid = _uuid;
|
|
|
- object.layerType = type;
|
|
|
- desc = $("#desc_vector_{{vector.getId()}}").html();
|
|
|
- object.bindPopup("<b>" + name + "</b> <br />" + desc + " <div style='text-align:center;margin-top:5px'><a target='_blank'href='{{path('admin_map_vector_edit',{id: vector.getId()})}}'>EDIT</a></div>");
|
|
|
+ /* Dar 200ms de espera, ya que esta instrucción puede ejecutarse
|
|
|
+ incluso antes de que el árbol de vectores haya
|
|
|
+ recibido la instrucción de recargarse. */
|
|
|
+ setTimeout(function() { selectElement(layer._id) }, 200);
|
|
|
+ }
|
|
|
|
|
|
- newLayer.addLayer(object);
|
|
|
+ });
|
|
|
|
|
|
- {% endfor %}
|
|
|
- //newLayer.visible = true;
|
|
|
- newLayer.addTo(map);
|
|
|
- controlLayers.addOverlay(newLayer, "{{layerName}}");
|
|
|
+ newLayer.class = 'layer';
|
|
|
+ newLayer.addLayer(object);
|
|
|
+ }
|
|
|
|
|
|
- {% endif %}
|
|
|
-
|
|
|
- {% endfor %}
|
|
|
- {% endif %}
|
|
|
+ window.layers[layer.id] = newLayer.addTo(map);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
</script>
|
|
@@ -106,23 +220,526 @@ function addLayersMap() {
|
|
|
{% endblock %}
|
|
|
|
|
|
{% block content %}
|
|
|
- <div class="row">
|
|
|
- <div class="col-md-12">
|
|
|
- <div class="cms-block cms-block-element">
|
|
|
- <div class="box">
|
|
|
- <div class="box-body">
|
|
|
- <div id="map" style="margin:0 auto; width: 95%; height: 700px; border: 1px solid #ccc"></div>
|
|
|
- </div>
|
|
|
+<div class="col-md-10">
|
|
|
+ <div class="cms-block cms-block-element">
|
|
|
+ <div class="box">
|
|
|
+ <div class="box-body">
|
|
|
+ <div id="map" style="margin:0 auto; width: 100%; height: calc(100vh - 190px); border: 1px solid #ccc"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+<div class="col-md-2">
|
|
|
+ <div class="box">
|
|
|
+ <div class="box-header">
|
|
|
+ <h4>Capas</h4>
|
|
|
+ <div class="box-body">
|
|
|
+ <div class="jstree-proton" id="jstree" style="max-height: calc(100vh - 250px); overflow-y: auto; overflow-x: hidden;"></div>
|
|
|
+ </div>
|
|
|
+ <button class="btn btn-default btn-xs" id="btnNewLayer"><i class="fa fa-file-o" data-toggle="modal" data-target="#modalNewLayer"></i></button>
|
|
|
+ <button onclick="refresh()" class="btn btn-default btn-xs"><i class="fa fa-refresh" aria-hidden="true"></i></button>
|
|
|
+ <button id="btnSave" class="btn btn-default btn-xs"><i class="fa fa-floppy-o" aria-hidden="true"></i></button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="box">
|
|
|
+ <div class="box-header">
|
|
|
+ <h4>Elementos</h4>
|
|
|
+ <br/>
|
|
|
+ <div class="btn-group">
|
|
|
+ <button class="btn btn-default btn-xs" onclick="new L.Draw.Polyline(map, drawControl.options.polyline).enable();"><i class="fa fa-share-alt" aria-hidden="true"></i></button>
|
|
|
+ <button class="btn btn-default btn-xs" onclick="new L.Draw.Polygon(map, drawControl.options.polygon).enable();"><i class="fa fa-star-o" aria-hidden="true"></i></button>
|
|
|
+ <button class="btn btn-default btn-xs" onclick="new L.Draw.Rectangle(map, drawControl.options.rectangle).enable();"><i class="fa fa-stop" aria-hidden="true"></i></button>
|
|
|
+ <button class="btn btn-default btn-xs" onclick="new L.Draw.Circle(map, drawControl.options.circle).enable();"><i class="fa fa-circle-o" aria-hidden="true"></i></button>
|
|
|
+ <button class="btn btn-default btn-xs" onclick="new L.Draw.Marker(map, drawControl.options.marker).enable();"><i class="fa fa-map-marker" aria-hidden="true"></i></button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div class="box-body">
|
|
|
+ <div class="jstree-proton" id="overlay_tree" style="max-height: calc(100vh - 450px); overflow-y: auto; overflow-x: hidden;"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+
|
|
|
+
|
|
|
+<!-- Modal Nueva Capa -->
|
|
|
+<div class="modal fade" id="modalNewLayer" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
|
|
|
+ <div class="modal-dialog" role="document">
|
|
|
+ <div class="modal-content">
|
|
|
+ <div class="modal-header">
|
|
|
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
|
+ <h4 class="modal-title" id="myModalLabel">Nueva Capa</h4>
|
|
|
+ </div>
|
|
|
+ <div class="modal-body">
|
|
|
+ <div class="container-fluid">
|
|
|
+ <label class="control-label col-md-3">Nombre</label>
|
|
|
+ <input class="form-control col-md-9" name="name" id="newLayerName"></input>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <div class="modal-footer">
|
|
|
+ <button type="button" class="btn btn-default" data-dismiss="modal">Cancelar</button>
|
|
|
+ <button onclick="createNewLayer()" type="submit" class="btn btn-primary">Crear</button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
-{% endblock %}
|
|
|
+</div>
|
|
|
+<!-- Fin - Modal Nueva Capa -->
|
|
|
+
|
|
|
+<!-- Modal Renombrar -->
|
|
|
+<div class="modal fade" id="modalRename" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
|
|
|
+ <div class="modal-dialog" role="document">
|
|
|
+ <div class="modal-content">
|
|
|
+ <div class="modal-header">
|
|
|
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
|
+ <h4 class="modal-title" id="myModalLabel">Renombrar</h4>
|
|
|
+ </div>
|
|
|
+ <div class="modal-body">
|
|
|
+ <div class="container-fluid">
|
|
|
+ <label class="control-label col-md-3">Nombre</label>
|
|
|
+ <input class="form-control col-md-9" name="name" id="newName"></input>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="modal-footer">
|
|
|
+ <button type="button" class="btn btn-default" data-dismiss="modal">Cancelar</button>
|
|
|
+ <button onclick="renameItem()" type="submit" class="btn btn-primary">Renombrar</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+<!-- Fin - Modal Renombrar -->
|
|
|
|
|
|
+<!-- Modal Renombrar -->
|
|
|
+<div class="modal fade" id="modalDelete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
|
|
|
+ <div class="modal-dialog modal-danger" role="document">
|
|
|
+ <div class="modal-content">
|
|
|
+ <div class="modal-header">
|
|
|
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
|
+ <h4 class="modal-title" id="myModalLabel">Borrar</h4>
|
|
|
+ </div>
|
|
|
+ <div class="modal-body">
|
|
|
+ <p>¿Está seguro de que desea borrar <span id="elementTypeCaption"?></span> "<span id="elementName"></span>"?</p>
|
|
|
+ </div>
|
|
|
+ <div class="modal-footer">
|
|
|
+ <button type="button" class="btn btn-danger" data-dismiss="modal">Cancelar</button>
|
|
|
+ <button onclick="deleteItem()" type="submit" class="btn btn-danger">Borrar</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+<!-- Fin - Modal Renombrar -->
|
|
|
|
|
|
-{% block list_filters_actions %}
|
|
|
{% endblock %}
|
|
|
|
|
|
-{% block list_filters %}
|
|
|
-{% endblock %}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+{% block javascripts %}
|
|
|
+{{ parent() }}
|
|
|
+<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.4/jstree.min.js"></script>
|
|
|
+<script>
|
|
|
+
|
|
|
+$(document).ready(function() {
|
|
|
+
|
|
|
+ $('#btnSave').click(function() {
|
|
|
+ /*
|
|
|
+ * Desactiva la edición en todas las capas,
|
|
|
+ * luego postea los datos existentes.
|
|
|
+ */
|
|
|
+ $.each(window.layers, function(id, myLayer) {
|
|
|
+ if (myLayer) {
|
|
|
+ myLayer.eachLayer(function(layer) {
|
|
|
+ layer.editing.disable();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ saveData();
|
|
|
+ });
|
|
|
+
|
|
|
+ // Defaults para el plugin JSTree
|
|
|
+ $.jstree.defaults.core.dblclick_toggle = false;
|
|
|
+ $.jstree.defaults.core.multiple = false;
|
|
|
+ $.jstree.defaults.checkbox.three_state = false;
|
|
|
+ $.jstree.defaults.checkbox.whole_node = false;
|
|
|
+ $.jstree.defaults.checkbox.tie_selection = false;
|
|
|
+ $.jstree.defaults.contextmenu.select_node = true;
|
|
|
+
|
|
|
+ $('#jstree').on('check_node.jstree uncheck_node.jstree', function (e, data) {
|
|
|
+ if (data.node.type == 'layer') {
|
|
|
+ if (data.node.state.checked) {
|
|
|
+ map.addLayer(layers[data.node.id]);
|
|
|
+ } else {
|
|
|
+ map.removeLayer(layers[data.node.id]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#jstree').on('select_node.jstree', function (e, data) {
|
|
|
+ if (data.node.type == 'layer') {
|
|
|
+ window.currentLayer = data.selected;
|
|
|
+ $('#overlay_tree').jstree(true).settings.core.data = makeOverlayTree(layers[data.selected]);
|
|
|
+ $('#overlay_tree').jstree(true).refresh();
|
|
|
+ }
|
|
|
+ toggleControls();
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#overlay_tree').on('select_node.jstree', function (e, data) {
|
|
|
+ var vectorData = getData('vectors', data.node.id);
|
|
|
+ map.eachLayer(function(layer){
|
|
|
+ if (layer._id == data.node.id) {
|
|
|
+ var popupContent = "<b>" + vectorData.name + "</b><br/>" + vectorData.description + " <div style='text-align:center;margin-top:5px'><a target='_blank' href='/admin/map/vector/" + vectorData.id + "/edit'>EDITAR</a></div>";
|
|
|
+ layer.bindPopup(popupContent).openPopup();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+
|
|
|
+ initializeTrees();
|
|
|
+});
|
|
|
+
|
|
|
+function getData(entity, id=null) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Dadas una entidad y opcionalmente un id, devuelve un JSON obtenido
|
|
|
+ * mediante una llamada AJAX a la API REST.
|
|
|
+ */
|
|
|
+
|
|
|
+ var result = null;
|
|
|
+
|
|
|
+ if (id == null) {
|
|
|
+ var url = "/api/" + entity
|
|
|
+ } else {
|
|
|
+ var url = "/api/" + entity + "/" + id
|
|
|
+ }
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ type: "GET",
|
|
|
+ dataType: "json",
|
|
|
+ async: false,
|
|
|
+ cache: false,
|
|
|
+ url: url,
|
|
|
+ success: function(data){
|
|
|
+ result = data;
|
|
|
+ },
|
|
|
+ error: function(XMLHttpRequest, textStatus, errorThrown) {
|
|
|
+ console.log("Status: " + textStatus); alert("Error: " + errorThrown);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return result;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function makeTree() {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Función que obtiene la información de las capas y se la entrega
|
|
|
+ * procesada al JSTree de capas.
|
|
|
+ */
|
|
|
+
|
|
|
+ var url = window.location.pathname;
|
|
|
+ var id = url.substring(url.lastIndexOf('/') + 1);
|
|
|
+ var mapData = getData('maps', id );
|
|
|
+ var result = [];
|
|
|
+
|
|
|
+ result.push({ "id" : "map_" + mapData.id, "parent" : "#", "text" : mapData.name,
|
|
|
+ "type": "map", a_attr: {class: "no_checkbox"}, state: { opened : true } });
|
|
|
+
|
|
|
+ for(var i = 0; i < mapData.layers.length; i++) {
|
|
|
+ var layer = mapData.layers[i];
|
|
|
+ result.push({ "id" : layer.id, "parent" : "map_" + mapData.id,
|
|
|
+ "text" : layer.name, "type" : "layer", state: { checked : true } });
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+function makeOverlayTree(layer) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Función que obtiene los vectores dentro de una capa y se los
|
|
|
+ * entrega procesados al JSTree de elementos.
|
|
|
+ */
|
|
|
+
|
|
|
+ result = [];
|
|
|
+
|
|
|
+ if (layer) {
|
|
|
+ var layerss = layer.getLayers();
|
|
|
+ for(var j = 0; j < layerss.length; j++) {
|
|
|
+ var vector = layerss[j];
|
|
|
+ result.push({ "id" :vector._id, "parent" : "#", "text" : vector.name,
|
|
|
+ "type": vector.layerType, a_attr: {class: "no_checkbox"} });
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+function customMenu(node) {
|
|
|
+
|
|
|
+ var items = {
|
|
|
+ editItem: {
|
|
|
+ label: "Editar",
|
|
|
+ action: function () { treeMenuEdit(node) } // No pasar la función directamente, sino la ejecuta al hacer click.
|
|
|
+ },
|
|
|
+ renameItem: {
|
|
|
+ label: "Renombrar",
|
|
|
+ action: function () {
|
|
|
+ if (node.type == 'layer') {
|
|
|
+ window.activeType = 'layer';
|
|
|
+ } else {
|
|
|
+ window.activeType = 'vector';
|
|
|
+ }
|
|
|
+ window.activeId = node.id;
|
|
|
+ $("#newName").val(node.text);
|
|
|
+ $("#modalRename").modal();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ deleteItem: {
|
|
|
+ label: "Borrar",
|
|
|
+ action: function () {
|
|
|
+ if (node.type == 'layer') {
|
|
|
+ $("#elementTypeCaption").text('la capa');
|
|
|
+ window.activeType = 'layer';
|
|
|
+ } else {
|
|
|
+ $("#elementTypeCaption").text('el elemento');
|
|
|
+ window.activeType = 'vector';
|
|
|
+ }
|
|
|
+ window.activeId = node.id;
|
|
|
+ $("#elementName").text(node.text);
|
|
|
+ $("#modalDelete").modal();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ return items;
|
|
|
+}
|
|
|
+
|
|
|
+function treeMenuEdit(node) {
|
|
|
+ if (node.type == "layer") {
|
|
|
+ var editor = new L.EditToolbar.Edit(map, {
|
|
|
+ featureGroup: drawControl.options.featureGroup,
|
|
|
+ selectedPathOptions: drawControl.options.edit.selectedPathOptions
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ var currentlayer = layers[[$('#jstree').jstree(true).get_selected()[0]]];
|
|
|
+ currentlayer.eachLayer(function(layer) {
|
|
|
+ if (layer._id == node.id) {
|
|
|
+ var vector = layer;
|
|
|
+ vector.editing.enable();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function guid() {
|
|
|
+ return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
|
|
+ s4() + '-' + s4() + s4() + s4();
|
|
|
+}
|
|
|
+
|
|
|
+function s4() {
|
|
|
+ return Math.floor((1 + Math.random()) * 0x10000)
|
|
|
+ .toString(16)
|
|
|
+ .substring(1);
|
|
|
+}
|
|
|
+
|
|
|
+function initializeTrees() {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Inicializa los controles JSTree
|
|
|
+ */
|
|
|
+
|
|
|
+ $('#jstree').jstree({
|
|
|
+
|
|
|
+ 'core' : {
|
|
|
+ "animation" : 200,
|
|
|
+ "check_callback" : true,
|
|
|
+ "data" : makeTree(),
|
|
|
+ "strings" : { 'Loading ...' : 'Cargando...' },
|
|
|
+ },
|
|
|
+
|
|
|
+ "types" : {
|
|
|
+ "map" : {
|
|
|
+ "icon" : "/images/tree/16x16/Map.png",
|
|
|
+ "valid_children" : ["layer"]
|
|
|
+ },
|
|
|
+ "layer" : {
|
|
|
+ "icon" : "/images/tree/16x16/Layers.png",
|
|
|
+ "valid_children" : ["vector","object"]
|
|
|
+ },
|
|
|
+ "#" : {
|
|
|
+ "valid_children" : []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "plugins" : [ "dnd", "contextmenu", "checkbox", "types", "changed", "wholerow" ],
|
|
|
+ contextmenu: {items: customMenu}
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#overlay_tree').jstree({
|
|
|
+
|
|
|
+ 'core' : {
|
|
|
+ "animation" : 0,
|
|
|
+ "check_callback" : false,
|
|
|
+ "data" : makeOverlayTree(),
|
|
|
+ "themes" : { "dots": false },
|
|
|
+ "strings" : { 'Loading ...' : 'Cargando...' },
|
|
|
+ },
|
|
|
+
|
|
|
+ "types" : {
|
|
|
+ "polygon" : {
|
|
|
+ "icon" : "/images/tree/16x16/Polygon.png",
|
|
|
+ "valid_children" : []
|
|
|
+ },
|
|
|
+ "circle" : {
|
|
|
+ "icon" : "/images/tree/16x16/Circle.png",
|
|
|
+ "valid_children" : []
|
|
|
+ },
|
|
|
+ "rectangle" : {
|
|
|
+ "icon" : "/images/tree/16x16/Rectangle.png",
|
|
|
+ "valid_children" : []
|
|
|
+ },
|
|
|
+ "polyline" : {
|
|
|
+ "icon" : "/images/tree/16x16/Polyline.png",
|
|
|
+ "valid_children" : []
|
|
|
+ },
|
|
|
+ "marker" : {
|
|
|
+ "icon" : "/images/tree/16x16/Marker.png",
|
|
|
+ "valid_children" : []
|
|
|
+ },
|
|
|
+ "#" : {
|
|
|
+ "valid_children" : []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "plugins" : [ "dnd", "contextmenu", "checkbox", "types", "changed", "wholerow" ],
|
|
|
+ contextmenu: {items: customMenu}
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function createNewLayer() {
|
|
|
+
|
|
|
+ var url = window.location.pathname;
|
|
|
+ var mapid = parseInt(url.substring(url.lastIndexOf('/') + 1));
|
|
|
+ var name = $('#newLayerName').val();
|
|
|
+
|
|
|
+ sendData = {name: name, map: mapid};
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ type: "POST",
|
|
|
+ url: "{{ path('post_layer') }}",
|
|
|
+ async: false,
|
|
|
+ data: JSON.stringify(sendData),
|
|
|
+ contentType: "application/json; charset=utf-8",
|
|
|
+ dataType: "json",
|
|
|
+ error: function(msg) {
|
|
|
+ console.log(msg.msg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#modalNewLayer').modal('hide');
|
|
|
+ refresh();
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function deleteItem() {
|
|
|
+ /*
|
|
|
+ * Dados el tipo de elemento y el id del mismo, realiza una petición HTTP
|
|
|
+ * a la API para que realice el borrado del mismo.
|
|
|
+ */
|
|
|
+
|
|
|
+ var itemId = window.activeId
|
|
|
+ var itemType = window.activeType
|
|
|
+
|
|
|
+ if (itemType == 'layer') {
|
|
|
+ var url = '/api/layers/' + itemId;
|
|
|
+ } else if (itemType == 'vector') {
|
|
|
+ var url = '/api/vectors/' + itemId;
|
|
|
+ }
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ type: "DELETE",
|
|
|
+ url: url,
|
|
|
+ async: false,
|
|
|
+ contentType: "application/json; charset=utf-8",
|
|
|
+ dataType: "json",
|
|
|
+ error: function(msg) {
|
|
|
+ console.log(msg.msg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#modalDelete').modal('hide');
|
|
|
+ refresh();
|
|
|
+}
|
|
|
+
|
|
|
+function renameItem() {
|
|
|
+ /*
|
|
|
+ * Dados el tipo de elemento y el id del mismo, realiza una petición HTTP
|
|
|
+ * a la API para cambiar el nombre.
|
|
|
+ */
|
|
|
+
|
|
|
+ var itemId = window.activeId
|
|
|
+ var itemType = window.activeType
|
|
|
+
|
|
|
+ if (itemType == 'layer') {
|
|
|
+ var url = '/api/layers/' + itemId;
|
|
|
+ } else if (itemType == 'vector') {
|
|
|
+ var url = '/api/vectors/' + itemId;
|
|
|
+ }
|
|
|
+
|
|
|
+ sendData = {id: itemId, name: $('#newName').val()};
|
|
|
+
|
|
|
+ $.ajax({
|
|
|
+ type: "PATCH",
|
|
|
+ url: url,
|
|
|
+ async: false,
|
|
|
+ data: JSON.stringify(sendData),
|
|
|
+ contentType: "application/json; charset=utf-8",
|
|
|
+ dataType: "json",
|
|
|
+ error: function(msg) {
|
|
|
+ console.log(msg.msg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#modalRename').modal('hide');
|
|
|
+
|
|
|
+ refresh();
|
|
|
+}
|
|
|
+
|
|
|
+function refresh() {
|
|
|
+ /* Recarga todos los elementos */
|
|
|
+
|
|
|
+ map.eachLayer(function (layer) {
|
|
|
+ if (layer._url != "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png") { //TODO: Buscar otra manera de matchear el mapa base.
|
|
|
+ map.removeLayer(layer);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ window.layers = null; /* Destruir global */
|
|
|
+ addLayersMap();
|
|
|
+
|
|
|
+ $('#jstree').jstree(true).settings.core.data = makeTree();
|
|
|
+ $('#overlay_tree').jstree(true).settings.core.data = makeOverlayTree(null);
|
|
|
+ $('#jstree').jstree(true).refresh();
|
|
|
+}
|
|
|
+
|
|
|
+function selectElement(elementId) {
|
|
|
+ /*
|
|
|
+ * Espera (preventivamente) a que los elementos se carguen e intenta
|
|
|
+ * seleccionar el elemento en cuestión
|
|
|
+ */
|
|
|
+
|
|
|
+ if ($('#overlay_tree').jstree().is_loading()) {
|
|
|
+ window.setTimeout(waitForLoad, 100); /* Reintenta en 100ms si está cargando */
|
|
|
+ } else {
|
|
|
+ $('#overlay_tree').jstree('select_node', elementId);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function toggleControls() {
|
|
|
+ if ($('#overlay_tree').jstree('get_selected') == '[]') {
|
|
|
+ $('#btnSave').prop('disabled', 'disabled');
|
|
|
+ } else {
|
|
|
+ $('#btnSave').removeProp('disabled');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+</script>
|
|
|
+{% endblock %}
|