776 lines
35 KiB
JavaScript
776 lines
35 KiB
JavaScript
(function (window, document, $) {
|
|
'use strict';
|
|
|
|
if (window.SIGVisorGis) { return; }
|
|
|
|
var api = window.SIGVisorGis = {};
|
|
var googlePromise = null;
|
|
|
|
function esc(value) {
|
|
return $('<div/>').text(value == null ? '' : String(value)).html();
|
|
}
|
|
|
|
function layerOf(feature) {
|
|
var p = feature && feature.properties || {};
|
|
return $.trim(String(p._sigCapa || p.Capa || p.capa || 'GIS')) || 'GIS';
|
|
}
|
|
|
|
function isSupported(g) {
|
|
return g && $.inArray(g.type, [
|
|
'Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon'
|
|
]) >= 0;
|
|
}
|
|
|
|
function loadGoogle(key) {
|
|
if (window.google && window.google.maps && window.google.maps.Data) {
|
|
return $.Deferred().resolve().promise();
|
|
}
|
|
if (googlePromise) { return googlePromise; }
|
|
var d = $.Deferred();
|
|
googlePromise = d.promise();
|
|
var callback = '__sigVisorGisMapsReady';
|
|
window[callback] = function () {
|
|
d.resolve();
|
|
try { delete window[callback]; } catch (_) { window[callback] = null; }
|
|
};
|
|
var s = document.createElement('script');
|
|
s.async = true;
|
|
s.defer = true;
|
|
s.src = 'https://maps.googleapis.com/maps/api/js?key=' + encodeURIComponent(key) + '&callback=' + callback;
|
|
var temporizador = window.setTimeout(function () {
|
|
googlePromise = null;
|
|
d.reject();
|
|
}, 30000);
|
|
d.always(function () {
|
|
window.clearTimeout(temporizador);
|
|
});
|
|
s.onerror = function () {
|
|
googlePromise = null;
|
|
d.reject();
|
|
};
|
|
document.head.appendChild(s);
|
|
return googlePromise;
|
|
}
|
|
|
|
function boundsOf(geo) {
|
|
var b = null;
|
|
function visit(v) {
|
|
if (!$.isArray(v)) { return; }
|
|
if (v.length >= 2 && typeof v[0] === 'number' && typeof v[1] === 'number') {
|
|
if (!b) { b = { minX:v[0], maxX:v[0], minY:v[1], maxY:v[1] }; }
|
|
else {
|
|
b.minX=Math.min(b.minX,v[0]); b.maxX=Math.max(b.maxX,v[0]);
|
|
b.minY=Math.min(b.minY,v[1]); b.maxY=Math.max(b.maxY,v[1]);
|
|
}
|
|
return;
|
|
}
|
|
$.each(v, function (_, x) { visit(x); });
|
|
}
|
|
$.each(geo.features || [], function (_, f) { if (isSupported(f.geometry)) { visit(f.geometry.coordinates); } });
|
|
return b;
|
|
}
|
|
|
|
function pathForLine(coords, project, close) {
|
|
if (!coords || !coords.length) { return ''; }
|
|
var p = project(coords[0]), r = ['M'+p[0]+','+p[1]];
|
|
for (var i=1;i<coords.length;i++) { p=project(coords[i]); r.push('L'+p[0]+','+p[1]); }
|
|
if (close) { r.push('Z'); }
|
|
return r.join(' ');
|
|
}
|
|
|
|
function pathsFor(g, project) {
|
|
var out=[];
|
|
if (g.type === 'LineString') { out.push(pathForLine(g.coordinates, project, false)); }
|
|
else if (g.type === 'MultiLineString') { $.each(g.coordinates, function(_,x){out.push(pathForLine(x,project,false));}); }
|
|
else if (g.type === 'Polygon') { $.each(g.coordinates,function(_,x){out.push(pathForLine(x,project,true));}); }
|
|
else if (g.type === 'MultiPolygon') {
|
|
$.each(g.coordinates,function(_,p){$.each(p,function(_,x){out.push(pathForLine(x,project,true));});});
|
|
}
|
|
return out.join(' ');
|
|
}
|
|
|
|
function limitesEncuadre(estado) {
|
|
var visibles = $.grep(estado.geo.features || [], function (figura) {
|
|
return isSupported(figura.geometry) && estado.visible[layerOf(figura)] !== false;
|
|
});
|
|
var lotificacion = $.grep(visibles, function (figura) {
|
|
var capa = estado.capas[layerOf(figura)];
|
|
return capa && capa.TipoCapa === 'Lotificacion';
|
|
});
|
|
var poligonos = $.grep(lotificacion, function (figura) {
|
|
return figura.geometry.type === 'Polygon' || figura.geometry.type === 'MultiPolygon';
|
|
});
|
|
// Los polígonos de lotes tienen prioridad sobre líneas auxiliares de la misma capa.
|
|
return boundsOf({ features: poligonos.length ? poligonos :
|
|
(lotificacion.length ? lotificacion : visibles) });
|
|
}
|
|
|
|
function encuadrarGoogle(estado) {
|
|
var limites = limitesEncuadre(estado);
|
|
if (!limites) {
|
|
// Sin capas visibles se conserva la última posición, sin incluir capas ocultas.
|
|
return;
|
|
}
|
|
var margenLongitud = limites.maxX === limites.minX ? 0.00005 : 0;
|
|
var margenLatitud = limites.maxY === limites.minY ? 0.00005 : 0;
|
|
var encuadre = new google.maps.LatLngBounds(
|
|
{ lat: limites.minY - margenLatitud, lng: limites.minX - margenLongitud },
|
|
{ lat: limites.maxY + margenLatitud, lng: limites.maxX + margenLongitud });
|
|
var ancho = estado.$root.find('[data-gis-map]').width();
|
|
var panelAbierto = estado.$root.find('[data-gis-alternar-capas]').attr('aria-expanded') === 'true';
|
|
estado.map.fitBounds(encuadre, {
|
|
top: 35,
|
|
bottom: 35,
|
|
left: 35,
|
|
right: panelAbierto && ancho > 700 ? 310 : 35
|
|
});
|
|
}
|
|
|
|
function actualizarDibujo(estado, recalcularEncuadre) {
|
|
if (estado.dataLayer) {
|
|
applyGoogleStyle(estado);
|
|
if (recalcularEncuadre) {
|
|
encuadrarGoogle(estado);
|
|
}
|
|
} else {
|
|
renderSvg(estado);
|
|
}
|
|
}
|
|
|
|
function guardarCapa(estado, capa, fila) {
|
|
var aviso = fila.find('[data-gis-estado-capa]');
|
|
fila.find('input, select, button').prop('disabled', true);
|
|
aviso.text('Guardando...');
|
|
$.ajax({
|
|
url: estado.$root.attr('data-gis-url'),
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
timeout: 30000,
|
|
data: {
|
|
metodo: 'GuardarCapa',
|
|
CveFraccionamientoEtapa: estado.$root.attr('data-gis-stage'),
|
|
NombreCapa: capa.NombreCapa,
|
|
TipoCapa: capa.TipoCapa,
|
|
Color: capa.Color,
|
|
EsVisible: capa.EsVisible
|
|
}
|
|
}).done(function (respuesta) {
|
|
aviso.text(respuesta.success ? 'Guardado' : 'No se guardó. Pulse Reintentar.');
|
|
fila.find('[data-gis-reintentar]').toggle(!respuesta.success);
|
|
}).fail(function () {
|
|
aviso.text('No se guardó. El cambio sólo se muestra en esta vista.');
|
|
fila.find('[data-gis-reintentar]').show();
|
|
}).always(function () {
|
|
fila.find('input, select, button').prop('disabled', false);
|
|
});
|
|
}
|
|
|
|
function renderLayers(estado) {
|
|
var contenedor = estado.$root.find('[data-gis-layers]').empty();
|
|
var boton = estado.$root.find('[data-gis-alternar-capas]');
|
|
var panel = estado.$root.find('[data-gis-panel-capas]');
|
|
panel.attr('id', 'gis-panel-' + estado.uid);
|
|
boton.attr('aria-controls', panel.attr('id'));
|
|
if (!boton.is('[data-sig-menu-capas-inicializado]')) {
|
|
boton.on('click.sigVisor', function () {
|
|
var abierto = boton.attr('aria-expanded') !== 'true';
|
|
panel.toggle(abierto);
|
|
boton.attr('aria-expanded', String(abierto));
|
|
});
|
|
boton.attr('data-sig-menu-capas-inicializado', '1');
|
|
}
|
|
|
|
$.each(estado.layers, function (indice, nombre) {
|
|
var capa = estado.capas[nombre];
|
|
var fila = $('<div class="sig-visor-gis__fila-capa"></div>').appendTo(contenedor);
|
|
var etiqueta = $('<label></label>').appendTo(fila);
|
|
var casilla = $('<input type="checkbox" />').prop('checked', capa.EsVisible).appendTo(etiqueta);
|
|
$('<span></span>').text(nombre).appendTo(etiqueta);
|
|
$('<span class="sig-visor-gis__cantidad"></span>').text(estado.layerCounts[nombre]).appendTo(etiqueta);
|
|
var geometria = capa.Geometria || '';
|
|
var descripcion = geometria.indexOf('Polygon') >= 0 ? 'Polígonos' :
|
|
geometria.indexOf('LineString') >= 0 ? 'Líneas' :
|
|
geometria.indexOf('Point') >= 0 ? 'Puntos' : 'Geometría mixta';
|
|
$('<span class="sig-visor-gis__geometria"></span>').text(descripcion).appendTo(fila);
|
|
var opciones = $('<div class="sig-visor-gis__opciones-capa"></div>').appendTo(fila);
|
|
var selector = $('<select class="form-control input-sm"></select>')
|
|
.attr('aria-label', 'Tipo de ' + nombre).appendTo(opciones);
|
|
$.each({ Agua: 'Línea de agua', Drenaje: 'Línea de drenaje',
|
|
Lotificacion: 'Lotificación', Pozos: 'Pozos', Otros: 'Otros' }, function (valor, texto) {
|
|
$('<option></option>').val(valor).text(texto).appendTo(selector);
|
|
});
|
|
selector.val(capa.TipoCapa);
|
|
var color = $('<input type="color" />').val(capa.Color)
|
|
.attr('aria-label', 'Color de ' + nombre).appendTo(opciones);
|
|
$('<p class="sig-visor-gis__aviso" data-gis-estado-capa role="status"></p>').appendTo(fila);
|
|
var reintentar = $('<button type="button" class="btn btn-xs btn-default" data-gis-reintentar>Reintentar</button>')
|
|
.hide().appendTo(fila);
|
|
fila.find('input, select').on('change.sigVisor', function () {
|
|
var recalcularEncuadre = capa.EsVisible !== casilla.prop('checked') ||
|
|
capa.TipoCapa !== selector.val();
|
|
capa.EsVisible = casilla.prop('checked');
|
|
capa.TipoCapa = selector.val();
|
|
capa.Color = color.val();
|
|
estado.visible[nombre] = capa.EsVisible;
|
|
actualizarDibujo(estado, recalcularEncuadre);
|
|
guardarCapa(estado, capa, fila);
|
|
});
|
|
reintentar.on('click.sigVisor', function () {
|
|
guardarCapa(estado, capa, fila);
|
|
});
|
|
fila.attr('data-sig-capa-inicializada', '1');
|
|
});
|
|
}
|
|
|
|
function claveFigura(figura) {
|
|
return figura && figura.id != null && $.trim(String(figura.id)) !== ''
|
|
? 'id:' + $.trim(String(figura.id)) : '';
|
|
}
|
|
|
|
function nombreLote(lote) {
|
|
return lote.Nombre || ('Lote ' + (lote.Numero || lote.CveFraccionamientoLote));
|
|
}
|
|
|
|
function loteVinculado(estado, clave) {
|
|
return $.grep(estado.lotes || [], function (lote) {
|
|
return lote.GISPoligonoClave === clave;
|
|
})[0];
|
|
}
|
|
|
|
function mostrarFichaLote(contenedor, lote) {
|
|
contenedor.empty();
|
|
var ficha = $('<dl class="sig-visor-gis__ficha-lote"></dl>').appendTo(contenedor);
|
|
$.each([
|
|
['Lote', nombreLote(lote)], ['Etapa', lote.Etapa], ['Tipo', lote.Tipo],
|
|
['Calle', lote.Calle], ['Catastro', lote.Catastro],
|
|
['Superficie', lote.MetrosCuadrados == null ? 'Sin registrar' :
|
|
Number(lote.MetrosCuadrados).toLocaleString('es-MX') + ' m²']
|
|
], function (indice, dato) {
|
|
$('<dt></dt>').text(dato[0]).appendTo(ficha);
|
|
$('<dd></dd>').text(dato[1] || 'Sin registrar')
|
|
.toggleClass('sig-visor-gis__superficie-lote', dato[0] === 'Superficie').appendTo(ficha);
|
|
});
|
|
}
|
|
|
|
function cargarLotes(estado) {
|
|
return $.ajax({
|
|
url: estado.$root.attr('data-gis-url'),
|
|
dataType: 'json',
|
|
cache: false,
|
|
timeout: 30000,
|
|
data: {
|
|
metodo: 'Context',
|
|
CveFraccionamientoEtapa: estado.$root.attr('data-gis-stage')
|
|
}
|
|
}).then(function (respuesta) {
|
|
if (!respuesta.success || !respuesta.data || !$.isArray(respuesta.data.Lotes)) {
|
|
return $.Deferred().reject().promise();
|
|
}
|
|
return respuesta;
|
|
});
|
|
}
|
|
|
|
function abrirLote(estado, figura) {
|
|
var clave = claveFigura(figura);
|
|
var modal = estado.$root.find('[data-gis-modal-lote]');
|
|
var mensaje = modal.find('[data-gis-mensaje-lote]');
|
|
estado.consultaLotesActual = (estado.consultaLotesActual || 0) + 1;
|
|
var consultaActual = estado.consultaLotesActual;
|
|
if (!modal.is('[data-sig-consulta-lotes-inicializada]')) {
|
|
modal.on('hide.bs.modal.sigVisorLotes', function () {
|
|
estado.consultaLotesActual++;
|
|
});
|
|
modal.attr('data-sig-consulta-lotes-inicializada', '1');
|
|
}
|
|
estado.figuraSeleccionada = figura;
|
|
estado.claveSeleccionada = clave;
|
|
actualizarDibujo(estado);
|
|
modal.find('[data-gis-clave-lote]').text('Polígono: ' + clave);
|
|
modal.find('[data-gis-datos-lote]').empty();
|
|
modal.find('[data-gis-seleccion-lote], [data-gis-vincular-lote]').hide();
|
|
mensaje.text('Consultando lotes de la etapa...');
|
|
if (document.fullscreenElement && document.exitFullscreen) {
|
|
document.exitFullscreen().catch(function () {});
|
|
}
|
|
var usaPanel = estado.$root.is('[data-sig-lotes-mapa-inicializado]');
|
|
if (usaPanel) {
|
|
estado.$root.find('[data-gis-info]').text('Consultando lote...').show();
|
|
} else {
|
|
modal.modal('show');
|
|
}
|
|
cargarLotes(estado).done(function (respuesta) {
|
|
if (estado.consultaLotesActual !== consultaActual || estado.claveSeleccionada !== clave ||
|
|
!$.contains(document, estado.$root[0])) {
|
|
return;
|
|
}
|
|
estado.lotes = respuesta.data.Lotes;
|
|
var lote = loteVinculado(estado, clave);
|
|
modal.find('[data-gis-titulo-lote]').text(lote ? nombreLote(lote) : 'Vincular polígono con lote');
|
|
mensaje.text('');
|
|
if (lote) {
|
|
mostrarVinculo(estado, figura, lote);
|
|
if (usaPanel) {
|
|
estado.$root.trigger('sig:loteSeleccionado', [lote]);
|
|
} else {
|
|
mostrarFichaLote(modal.find('[data-gis-datos-lote]'), lote);
|
|
}
|
|
return;
|
|
}
|
|
estado.$root.find('[data-gis-info]').text('Polígono sin lote vinculado.');
|
|
modal.modal('show');
|
|
var selector = modal.find('[data-gis-selector-lote]').empty();
|
|
$('<option></option>').val('').text('Seleccione un lote').appendTo(selector);
|
|
$.each(estado.lotes, function (indice, disponible) {
|
|
if (disponible.EsActivo && !disponible.GISPoligonoClave) {
|
|
$('<option></option>').val(disponible.CveFraccionamientoLote)
|
|
.text(nombreLote(disponible)).appendTo(selector);
|
|
}
|
|
});
|
|
modal.find('[data-gis-seleccion-lote], [data-gis-vincular-lote]').show();
|
|
if (selector.find('option').length === 1) {
|
|
mensaje.text('No hay lotes activos disponibles en esta etapa.');
|
|
}
|
|
}).fail(function () {
|
|
if (estado.consultaLotesActual !== consultaActual || estado.claveSeleccionada !== clave ||
|
|
!$.contains(document, estado.$root[0])) {
|
|
return;
|
|
}
|
|
mensaje.text('No fue posible consultar los lotes. Cierre y vuelva a seleccionar el polígono.');
|
|
estado.$root.find('[data-gis-info]').text(mensaje.text()).show();
|
|
});
|
|
var boton = modal.find('[data-gis-vincular-lote]');
|
|
if (!boton.is('[data-sig-vincular-lote-inicializado]')) {
|
|
boton.on('click.sigVisorLote', function () {
|
|
var lote = parseInt(modal.find('[data-gis-selector-lote]').val(), 10) || 0;
|
|
if (!lote) {
|
|
mensaje.text('Seleccione un lote disponible.');
|
|
return;
|
|
}
|
|
var figuraActual = estado.figuraSeleccionada;
|
|
modal.find('button, select').prop('disabled', true);
|
|
mensaje.text('Guardando vínculo...');
|
|
$.ajax({
|
|
url: estado.$root.attr('data-gis-url'),
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
timeout: 30000,
|
|
data: {
|
|
metodo: 'VincularLote',
|
|
CveFraccionamientoEtapa: estado.$root.attr('data-gis-stage'),
|
|
CveFraccionamientoLote: lote,
|
|
ClavePoligono: claveFigura(figuraActual)
|
|
}
|
|
}).done(function (respuesta) {
|
|
if (!respuesta.success) {
|
|
mensaje.text(respuesta.message || 'No fue posible vincular el lote.');
|
|
return;
|
|
}
|
|
var vinculado = $.grep(estado.lotes, function (elemento) {
|
|
return elemento.CveFraccionamientoLote === lote;
|
|
})[0];
|
|
vinculado.GISPoligonoClave = claveFigura(figuraActual);
|
|
mostrarVinculo(estado, figuraActual, vinculado);
|
|
mostrarFichaLote(modal.find('[data-gis-datos-lote]'), vinculado);
|
|
modal.find('[data-gis-seleccion-lote], [data-gis-vincular-lote]').hide();
|
|
mensaje.text('Lote vinculado correctamente.');
|
|
actualizarDibujo(estado);
|
|
if (estado.$root.is('[data-sig-lotes-mapa-inicializado]')) {
|
|
modal.modal('hide');
|
|
estado.$root.trigger('sig:loteSeleccionado', [vinculado]);
|
|
}
|
|
}).fail(function (respuesta) {
|
|
mensaje.text(respuesta.responseJSON && respuesta.responseJSON.message ||
|
|
'No se pudo confirmar el guardado. Cierre y vuelva a seleccionar el polígono.');
|
|
}).always(function () {
|
|
modal.find('button, select').prop('disabled', false);
|
|
});
|
|
});
|
|
boton.attr('data-sig-vincular-lote-inicializado', '1');
|
|
}
|
|
}
|
|
|
|
function mostrarVinculo(estado, figura, lote) {
|
|
var informacion = estado.$root.find('[data-gis-info]').empty().show();
|
|
$('<strong></strong>').text(layerOf(figura)).appendTo(informacion);
|
|
$('<br />').appendTo(informacion);
|
|
$('<button type="button" class="sig-visor-gis__enlace-lote"></button>')
|
|
.text(nombreLote(lote)).on('click.sigVisorLote', function () {
|
|
abrirLote(estado, figura);
|
|
}).appendTo(informacion);
|
|
}
|
|
|
|
function featureInfo(estado, figura) {
|
|
var propiedades = figura.properties || {};
|
|
var informacion = estado.$root.find('[data-gis-info]').empty().show();
|
|
$('<strong></strong>').text(layerOf(figura)).appendTo(informacion);
|
|
var capa = estado.capas[layerOf(figura)];
|
|
var tipo = figura.geometry && figura.geometry.type;
|
|
estado.claveSeleccionada = claveFigura(figura);
|
|
actualizarDibujo(estado);
|
|
if (capa && capa.TipoCapa === 'Lotificacion' &&
|
|
(tipo === 'Polygon' || tipo === 'MultiPolygon')) {
|
|
if (!estado.claveSeleccionada || estado.claveSeleccionada.length > 100) {
|
|
$('<p></p>').text('Este polígono necesita una clave GIS válida y única.').appendTo(informacion);
|
|
return;
|
|
}
|
|
abrirLote(estado, figura);
|
|
return;
|
|
}
|
|
$.each(propiedades, function (nombre, valor) {
|
|
if (nombre.indexOf('_sig') !== 0 && valor != null && valor !== '') {
|
|
$('<span></span>').text(nombre + ': ' + valor).appendTo(informacion);
|
|
}
|
|
});
|
|
}
|
|
|
|
function applyGoogleStyle(state) {
|
|
state.dataLayer.setStyle(function (f) {
|
|
var layer = String(f.getProperty('_sigCapa') || 'GIS');
|
|
var type = f.getGeometry() && f.getGeometry().getType();
|
|
var visible = state.visible[layer] !== false;
|
|
var color = state.capas[layer] ? state.capas[layer].Color : '#1976D2';
|
|
var seleccionado = state.claveSeleccionada && state.claveSeleccionada === 'id:' + String(f.getId()).trim();
|
|
return {
|
|
visible: visible,
|
|
clickable: visible,
|
|
fillOpacity: type === 'Polygon' || type === 'MultiPolygon' ? 0.22 : 0,
|
|
strokeWeight: seleccionado ? 5 : (type === 'LineString' || type === 'MultiLineString' ? 3 : 2),
|
|
strokeColor: seleccionado ? '#FF8F00' : color,
|
|
fillColor: color,
|
|
icon: {
|
|
path: google.maps.SymbolPath.CIRCLE,
|
|
scale: 5,
|
|
fillColor: color,
|
|
fillOpacity: 1,
|
|
strokeColor: '#FFFFFF',
|
|
strokeWeight: 1
|
|
}
|
|
};
|
|
});
|
|
}
|
|
|
|
function renderGoogle(state) {
|
|
var el = state.$root.find('[data-gis-map]')[0];
|
|
$(el).empty();
|
|
state.map = new google.maps.Map(el, {
|
|
center: { lat: 29.072967, lng: -110.955919 },
|
|
zoom: 16,
|
|
maxZoom: 21,
|
|
zoomControl: true,
|
|
zoomControlOptions: { position: google.maps.ControlPosition.LEFT_BOTTOM },
|
|
mapTypeId: 'roadmap'
|
|
});
|
|
var controlCapas = state.$root.find('[data-gis-control-capas]')[0];
|
|
controlCapas.style.position = 'relative';
|
|
controlCapas.style.top = '0';
|
|
controlCapas.style.right = '0';
|
|
controlCapas.style.margin = '10px';
|
|
state.map.controls[google.maps.ControlPosition.RIGHT_TOP].push(controlCapas);
|
|
state.dataLayer = new google.maps.Data({map:state.map});
|
|
state.dataLayer.addGeoJson(state.geo);
|
|
applyGoogleStyle(state);
|
|
state.dataLayer.addListener('click', function(e){
|
|
var props={}; e.feature.forEachProperty(function(v,k){props[k]=v;});
|
|
featureInfo(state, { id: e.feature.getId(), properties: props,
|
|
geometry: { type: e.feature.getGeometry().getType() } });
|
|
});
|
|
encuadrarGoogle(state);
|
|
}
|
|
|
|
function renderSvg(state) {
|
|
state.dataLayer = null;
|
|
var controlCapas = state.$root.find('[data-gis-control-capas]');
|
|
controlCapas.appendTo(state.$root.find('.sig-visor-gis__contenedor'));
|
|
controlCapas.css({ position: '', top: '', right: '', margin: '' });
|
|
var $map=state.$root.find('[data-gis-map]').empty(), el=$map[0];
|
|
var b = limitesEncuadre(state) || state.ultimoEncuadre;
|
|
state.ultimoEncuadre = b;
|
|
if(!b){$map.html('<div class="alert alert-warning">El GIS no contiene geometrías visibles.</div>');return;}
|
|
var w=Math.max($map.width()||800,300), h=Math.max($map.height()||430,300), m=18;
|
|
var rx=b.maxX-b.minX||1, ry=b.maxY-b.minY||1, scale=Math.min((w-m*2)/rx,(h-m*2)/ry);
|
|
var ox=(w-rx*scale)/2, oy=(h-ry*scale)/2;
|
|
function project(p){return [ox+(p[0]-b.minX)*scale,h-(oy+(p[1]-b.minY)*scale)];}
|
|
var svg=document.createElementNS('http://www.w3.org/2000/svg','svg');
|
|
svg.setAttribute('viewBox','0 0 '+w+' '+h); svg.setAttribute('class','sig-visor-gis__svg');
|
|
$.each(state.geo.features||[],function(_,f){
|
|
if(!isSupported(f.geometry) || state.visible[layerOf(f)]===false){return;}
|
|
var type=f.geometry.type, node;
|
|
var colorCapa = state.capas[layerOf(f)].Color;
|
|
if(type==='Point'||type==='MultiPoint'){
|
|
var pts=type==='Point'?[f.geometry.coordinates]:f.geometry.coordinates;
|
|
$.each(pts,function(_,pt){var q=project(pt);node=document.createElementNS('http://www.w3.org/2000/svg','circle');node.setAttribute('cx',q[0]);node.setAttribute('cy',q[1]);node.setAttribute('r','4');node.setAttribute('class','sig-visor-gis__point');node.style.fill=colorCapa;node.addEventListener('click',function(){featureInfo(state,f);});svg.appendChild(node);});
|
|
} else {
|
|
var d=pathsFor(f.geometry,project); if(!d){return;}
|
|
node=document.createElementNS('http://www.w3.org/2000/svg','path');node.setAttribute('d',d);
|
|
node.setAttribute('class',(type.indexOf('Polygon')>=0?'sig-visor-gis__polygon':'sig-visor-gis__line'));
|
|
node.style.stroke = state.claveSeleccionada === claveFigura(f) ? '#FF8F00' : colorCapa;
|
|
node.style.strokeWidth = state.claveSeleccionada === claveFigura(f) ? '5' : '2';
|
|
if (type.indexOf('Polygon') >= 0) {
|
|
node.style.fill = colorCapa;
|
|
node.style.fillOpacity = '0.22';
|
|
}
|
|
node.setAttribute('fill-rule','evenodd'); node.addEventListener('click',function(){featureInfo(state,f);}); svg.appendChild(node);
|
|
}
|
|
});
|
|
el.appendChild(svg);
|
|
$('<div class="sig-visor-gis__note">Vista GIS · Active Google Maps en configuración para usar mapa base.</div>').appendTo($map);
|
|
}
|
|
|
|
function init(raiz) {
|
|
var elemento = $(raiz);
|
|
if (elemento.attr('data-sig-visor-gis-inicializado') === '1' ||
|
|
elemento.attr('data-sig-visor-gis-cargando') === '1') {
|
|
return;
|
|
}
|
|
|
|
var etapa = parseInt(elemento.attr('data-gis-stage'), 10) || 0;
|
|
var direccion = elemento.attr('data-gis-url');
|
|
if (!etapa || !direccion) {
|
|
return;
|
|
}
|
|
|
|
var estado = {
|
|
$root: elemento,
|
|
uid: Math.random().toString(36).slice(2),
|
|
geo: null,
|
|
layers: [],
|
|
layerCounts: Object.create(null),
|
|
visible: Object.create(null),
|
|
capas: Object.create(null),
|
|
dataLayer: null
|
|
};
|
|
elemento.data('sigVisorGis', estado);
|
|
elemento.find('[data-gis-file]').text(elemento.attr('data-gis-file-name') || '');
|
|
elemento.attr('data-sig-visor-gis-cargando', '1');
|
|
|
|
function terminar() {
|
|
elemento.attr('data-sig-visor-gis-inicializado', '1');
|
|
elemento.removeAttr('data-sig-visor-gis-cargando');
|
|
}
|
|
|
|
function mostrarError(mensaje) {
|
|
elemento.removeAttr('data-sig-visor-gis-cargando');
|
|
elemento.find('[data-gis-map]').empty().append(
|
|
$('<div class="alert alert-danger"></div>').text(mensaje));
|
|
}
|
|
|
|
function mostrarAlternativa() {
|
|
if (!$.contains(document, elemento[0])) {
|
|
return;
|
|
}
|
|
try {
|
|
renderSvg(estado);
|
|
terminar();
|
|
} catch (error) {
|
|
mostrarError('No fue posible dibujar el GIS de la etapa.');
|
|
}
|
|
}
|
|
|
|
$.ajax({
|
|
url: direccion,
|
|
type: 'GET',
|
|
dataType: 'text',
|
|
cache: false,
|
|
timeout: 30000,
|
|
data: {
|
|
metodo: 'File',
|
|
CveFraccionamientoEtapa: etapa
|
|
}
|
|
}).done(function (texto) {
|
|
if (!$.contains(document, elemento[0])) {
|
|
return;
|
|
}
|
|
try {
|
|
var geometria = JSON.parse(String(texto || '').replace(/^\uFEFF/, ''));
|
|
if (!geometria || geometria.type !== 'FeatureCollection' ||
|
|
!$.isArray(geometria.features)) {
|
|
throw new Error();
|
|
}
|
|
geometria.features = $.grep(geometria.features, function (figura) {
|
|
return figura && isSupported(figura.geometry);
|
|
});
|
|
if (!geometria.features.length) {
|
|
throw new Error();
|
|
}
|
|
estado.geo = geometria;
|
|
var colores = ['#1976D2', '#D84315', '#388E3C', '#8E24AA', '#00838F',
|
|
'#C2185B', '#827717', '#5D4037', '#455A64', '#F9A825'];
|
|
$.each(geometria.features, function (indice, figura) {
|
|
var capa = layerOf(figura);
|
|
figura.properties = figura.properties || {};
|
|
figura.properties._sigCapa = capa;
|
|
if (!estado.layerCounts[capa]) {
|
|
var nombre = capa.toLowerCase();
|
|
estado.capas[capa] = {
|
|
NombreCapa: capa,
|
|
TipoCapa: nombre.indexOf('lotific') >= 0 ? 'Lotificacion' :
|
|
nombre.indexOf('pozo') >= 0 ? 'Pozos' :
|
|
nombre.indexOf('drenaje') >= 0 ? 'Drenaje' :
|
|
nombre.indexOf('agua') >= 0 ? 'Agua' : 'Otros',
|
|
Color: colores[estado.layers.length % colores.length],
|
|
EsVisible: true,
|
|
Geometria: figura.geometry.type
|
|
};
|
|
estado.layers.push(capa);
|
|
estado.layerCounts[capa] = 0;
|
|
estado.visible[capa] = true;
|
|
} else if (estado.capas[capa].Geometria !== figura.geometry.type) {
|
|
estado.capas[capa].Geometria = 'Mixta';
|
|
}
|
|
estado.layerCounts[capa]++;
|
|
});
|
|
$.ajax({
|
|
url: direccion,
|
|
type: 'GET',
|
|
dataType: 'json',
|
|
cache: false,
|
|
timeout: 30000,
|
|
data: { metodo: 'Capas', CveFraccionamientoEtapa: etapa }
|
|
}).done(function (respuesta) {
|
|
if (!respuesta.success || !$.isArray(respuesta.data)) {
|
|
elemento.find('[data-gis-estado-capas]').text('No se pudo leer la configuración guardada.');
|
|
return;
|
|
}
|
|
$.each(respuesta.data, function (indice, capa) {
|
|
if (estado.capas[capa.NombreCapa]) {
|
|
estado.capas[capa.NombreCapa] = capa;
|
|
estado.visible[capa.NombreCapa] = capa.EsVisible;
|
|
}
|
|
});
|
|
}).fail(function () {
|
|
elemento.find('[data-gis-estado-capas]').text(
|
|
'No se pudo leer la configuración guardada. Se muestran valores iniciales.');
|
|
}).always(function () {
|
|
if (!$.contains(document, elemento[0])) {
|
|
return;
|
|
}
|
|
renderLayers(estado);
|
|
var habilitado = elemento.attr('data-gis-google-enabled') === '1';
|
|
var clave = elemento.attr('data-gis-google-key') || '';
|
|
if (habilitado && clave) {
|
|
loadGoogle(clave).done(function () {
|
|
if (!$.contains(document, elemento[0])) {
|
|
return;
|
|
}
|
|
try {
|
|
renderGoogle(estado);
|
|
terminar();
|
|
} catch (error) {
|
|
mostrarAlternativa();
|
|
}
|
|
}).fail(mostrarAlternativa);
|
|
} else {
|
|
mostrarAlternativa();
|
|
}
|
|
});
|
|
} catch (error) {
|
|
mostrarError('El archivo GIS guardado no tiene un formato compatible.');
|
|
}
|
|
}).fail(function () {
|
|
mostrarError('No fue posible cargar el GIS de la etapa.');
|
|
});
|
|
}
|
|
|
|
api.redimensionar = function (raiz) {
|
|
var estado = $(raiz).data('sigVisorGis');
|
|
if (!estado || !estado.geo) {
|
|
return;
|
|
}
|
|
if (estado.map) {
|
|
var centro = estado.map.getCenter();
|
|
var zoom = estado.map.getZoom();
|
|
google.maps.event.trigger(estado.map, 'resize');
|
|
if (centro) {
|
|
estado.map.setCenter(centro);
|
|
}
|
|
if (zoom != null) {
|
|
estado.map.setZoom(zoom);
|
|
}
|
|
} else if (estado.$root.is('[data-sig-visor-gis-inicializado]')) {
|
|
renderSvg(estado);
|
|
}
|
|
};
|
|
|
|
api.limpiarSeleccion = function (raiz, claveLote) {
|
|
var estado = $(raiz).data('sigVisorGis');
|
|
if (!estado) {
|
|
return;
|
|
}
|
|
var seleccionAfectada = false;
|
|
$.each(estado.lotes || [], function (indice, lote) {
|
|
if (String(lote.CveFraccionamientoLote) === String(claveLote)) {
|
|
seleccionAfectada = estado.claveSeleccionada === lote.GISPoligonoClave;
|
|
lote.GISPoligonoClave = '';
|
|
}
|
|
});
|
|
if (seleccionAfectada) {
|
|
estado.claveSeleccionada = null;
|
|
estado.$root.find('[data-gis-info]').empty();
|
|
}
|
|
actualizarDibujo(estado);
|
|
};
|
|
|
|
api.verLote = function (raiz, claveLote) {
|
|
var estado = $(raiz).data('sigVisorGis');
|
|
if (!estado || !estado.geo) {
|
|
return;
|
|
}
|
|
estado.consultaLotesActual = (estado.consultaLotesActual || 0) + 1;
|
|
var consulta = estado.consultaLotesActual;
|
|
var informacion = estado.$root.find('[data-gis-info]').text('Consultando lote...').show();
|
|
cargarLotes(estado).done(function (respuesta) {
|
|
if (consulta !== estado.consultaLotesActual || !$.contains(document, estado.$root[0])) {
|
|
return;
|
|
}
|
|
estado.lotes = respuesta.data.Lotes;
|
|
var lote = $.grep(estado.lotes, function (elemento) {
|
|
return String(elemento.CveFraccionamientoLote) === String(claveLote) && elemento.EsActivo;
|
|
})[0];
|
|
var figura = lote && $.grep(estado.geo.features, function (elemento) {
|
|
return claveFigura(elemento) === lote.GISPoligonoClave;
|
|
})[0];
|
|
if (!figura) {
|
|
informacion.text('Este lote no tiene un polígono vinculado en el archivo actual. Seleccione un polígono libre para vincularlo.');
|
|
estado.$root[0].scrollIntoView({ block: 'center' });
|
|
return;
|
|
}
|
|
var capa = layerOf(figura);
|
|
estado.visible[capa] = true;
|
|
estado.capas[capa].EsVisible = true;
|
|
renderLayers(estado);
|
|
estado.claveSeleccionada = claveFigura(figura);
|
|
estado.figuraSeleccionada = figura;
|
|
actualizarDibujo(estado);
|
|
mostrarVinculo(estado, figura, lote);
|
|
estado.$root.trigger('sig:loteSeleccionado', [lote]);
|
|
if (estado.map) {
|
|
var limites = boundsOf({ features: [figura] });
|
|
if (limites) {
|
|
estado.map.fitBounds(new google.maps.LatLngBounds(
|
|
{ lat: limites.minY, lng: limites.minX },
|
|
{ lat: limites.maxY, lng: limites.maxX }), 70);
|
|
}
|
|
}
|
|
}).fail(function () {
|
|
if (consulta === estado.consultaLotesActual) {
|
|
informacion.text('No fue posible consultar el vínculo del lote. Inténtelo nuevamente.');
|
|
}
|
|
});
|
|
};
|
|
|
|
function scan() {
|
|
if (window.SIGLotesEtapa) {
|
|
window.SIGLotesEtapa.restaurarMapas();
|
|
}
|
|
$('.sig-visor-gis[data-gis-stage]').each(function () {
|
|
init(this);
|
|
});
|
|
}
|
|
api.init=scan;
|
|
api.ensureGoogleMaps=loadGoogle;
|
|
$(scan);
|
|
if(window.Sys&&Sys.WebForms&&Sys.WebForms.PageRequestManager){
|
|
try{Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(){scan();});}catch(_){ }
|
|
}
|
|
})(window, document, window.jQuery);
|