# HG changeset patch # User cin # Date 1503326820 -10800 # Node ID f0035923ff3e23ce7582cf56a3bbae9e530896f2 # Parent 9c0943c68a90bfb9f93dbe8d02eef009e17322b6 добавлена библиотека для работы с openlayers 3+ diff -r 9c0943c68a90 -r f0035923ff3e src/djol/BaseLayer.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/BaseLayer.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,44 @@ +define([ + "implab/text/template-compile", + "dojo/_base/declare", + "dojo/_base/lang", + "ol"], + function (compile, declare, lang, ol) { + return declare([ol.layer.Layer], { + + name: null, + + displayName: null, + + identifyResultTemplate: null, + + searchResultTemplate: null, + + constructor: function () { + lang.mixin(this, arguments[0]); + var identifyCompiledTemplate = null, searchCompiledTemplate = null; + if (this.identifyResultTemplate) { + identifyCompiledTemplate = compile(this.identifyResultTemplate); + } + if (this.searchResultTemplate) { + searchCompiledTemplate = compile(this.searchResultTemplate); + } + }, + + /** Возвращает массив строк, каждая строка - результат поиска приведенный к шаблонному виду + @options {Object} + @str {String} поисковая строка + @bbox {Object} bound box, в рамках которого осуществлять поиск + */ + getSearchResult: function (options) { + console.warn("Метод необходимо переопределить для для слоя конкретного типа!"); + }, + /** Возвращает массив строк, каждая строка - результат идентификации приведенный к шаблонному виду + @options {Object} + @coordinates {Array} массив описывающий координаты точки идентификации + */ + getItentifyResult: function (coordinates) { + console.warn("Метод необходимо переопределить для для слоя конкретного типа!"); + } + }); + }) \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/ClearTool.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/ClearTool.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,19 @@ +define (["dojo/_base/declare", "./_OneshotTool", "implab/safe"] , function(declare, _OneshotTool, safe) { + return declare([_OneshotTool], { + tools : null, + + constructor : function(opts) { + safe.mixin(this,opts, ["tools"]); + }, + + invoke : function() { + if (this.tools) { + this.log("Clear {0} tools", this.tools.length); + safe.each(this.tools, function(tool) { + if (tool.clear) + tool.clear(); + }); + } + } + }); +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/DeactivationTool.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/DeactivationTool.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,14 @@ +define(["dojo/_base/declare", "./_ToolBase"],function(declare, _ToolBase) { + + // Инструмент, выключает текущий активный инструмент + // Данный инструмент ничго не делает, но при его активации будет + // деактивирован предыдущий инструмент + return declare([_ToolBase], { + + // данный инструмент не может быть активным, поэтому данный метод + // переопределяется и возвращает всегда false + onActivating : function() { + return false; + } + }); +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/DistanceMeasureTool.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/DistanceMeasureTool.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,63 @@ +define([ + "dojo/_base/declare", + "implab/safe", + "./MeasureToolBase", + "implab/text/format", + "dojo/i18n!./format/nls/units", + "ol" ], + +function(declare, safe, MeasureToolBase, format, units, ol) { + return declare([ MeasureToolBase ], { + + isGeodesic : true, + + units : 'metric', + + constructor : function(opts) { + if (opts) + safe.mixin(this,opts,["isGeodesic", "units"]); + }, + + _createDraw : function(source) { + return new ol.interaction.Draw( + { + source : source, + type : "LineString", + style : this.drawStyle + }); + }, + + _formatTooltip : function(sketch, proj) { + var length = 0; + if (this.isGeodesic) { + var points = sketch.getGeometry().getCoordinates(); + var t = ol.proj.getTransform(proj, "EPSG:4326"); + for (var i = 0; i < points.length - 1; i++) { + length += this.wgs84Sphere.haversineDistance( + t(points[i]), + t(points[i + 1])); + } + } else { + length = sketch.getGeometry().getLength(); + } + + var mpu, unitName; + switch (this.units) { + case "nautical": + mpu = 1852; + unitName = units.nmiles; + break; + default: + mpu = 1000; + unitName = units.kilometers; + } + + if (length >= mpu) { + return format("{0:#.0#}{1}", length / mpu, unitName); + } else { + return format("{0:#0.0#}{1}", length, units.meters); + } + } + + }); +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/DynamicStyle.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/DynamicStyle.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,119 @@ +define([ "./declare-style", "dojo/_base/declare", "ol", "implab/safe" ], + +function(declare, dojoDeclare, ol, safe) { + return declare([], { + _cache : null, + _getKey : null, + _getZoom : null, + + defaultStyle : null, + + style : null, + + styleFunction : null, + + filter : null, + + constructor : function(opts) { + if (opts) + dojoDeclare.safeMixin(this, opts); + + this._cache = {}; + + if (this.zoom) { + if (this.zoom instanceof Function) { + this._getZoom = this.zoom; + } else { + var levels = [], max = "max"; + for ( var p in this.zoom) { + if (safe.isNumber(this.zoom[p])) + levels.push({ + name : p, + zoom : Number(this.zoom[p]) + }); + else if (this.zoom[p] == "max") + max = p; + } + + levels.sort(function(x, y) { + return x.zoom - y.zoom; + }); + + this.zoomMax = max; + this.zoomLevels = levels; + + this._getZoom = function(z) { + for (var i = 0; i < levels.length; i++) { + if (z <= levels[i].zoom) + return levels[i].name; + } + return max; + }; + } + } else { + this._getZoom = function(z) { + return "max"; + }; + } + + if (this.key) { + if (this.key instanceof Function) { + this._getKey = this.key; + } else if (typeof this.key === "string") { + this._getKey = function(ft) { + return ft.get(this.key); + }; + } else { + this._getKey = function(ft, z) { + var k = this.key[z]; + if (k instanceof Function) + return k.call(this, ft, z); + else if (typeof k == "string") + return ft.get(k); + else + return this.defaultStyle; + }; + } + } else { + this._getKey = function() { + return this.defaultStyle; + }; + } + + if (this.style) { + if (this.style instanceof Function) { + this._style = this.style; + } else { + this._style = function(ft, res, key, zoom) { + var s = this.style[zoom]; + return s && (s instanceof Function) ? s.apply( + this, + arguments) : s; + }; + } + } + }, + + getFeatureStyle : function(ft, res) { + safe.argumentNotNull(ft, "ft"); + + if (this.filter && this.filter(ft) === false) + return null; + + var z = this._getZoom(res); + var k = this._getKey(ft, z); + + var cid = [ k, z ].join('-'); + + var style = this._cache[cid]; + if (!style) { + style = this._style ? this._style(ft, res, k, z) : null; + this._cache[cid] = style; + } + + + return safe.isNull(style) || style instanceof Array ? style : [ style ]; + } + + }); +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/IdentificationTool.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/IdentificationTool.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,246 @@ +define([ + "dijit/layout/ContentPane", + "dojo/_base/declare", + "dojo/Deferred", + "dojo/dom-construct", + "dojo/dom-class", + "dojo/on", + "dojo/promise/all", + "dojo/when", + "implab/safe", + "ol", + "./listen", + "./IdentifyGroup", + "./_ToolBase", + "./PopupContainer" + ], + + function ( + ContentPane, + declare, + Deffered, + domConstruct, + domClass, + on, + promiseAll, + when, + safe, + ol, + listen, + IdentifyGroup, + _ToolBase, + PopupContainer) { + return declare([_ToolBase], { + /** + * массив обработчиков openLayers, которые необходимо удалить при + * деактивации + */ + _handlers: null, + /** + * widget карты + */ + _map: null, + /** + * openLayers map + */ + _olMap: null, + /** + * Массив overlays содержащих popupContainers + */ + _popupOverlays: null, + /** + * Массив popups контейнеров + */ + _popupContainers: null, + /** + * Режим работы инструмента идентификации + * + * @value {String} "single"||"multiple" + */ + mode: null, + /** + * Режимы + */ + appManager: null, + + constructor: function (options) { + safe.argumentNotNull(options, "options"); + safe.argumentNotNull(options.map, "options.map"); + safe.argumentNotNull(options.appManager, "options.appManager"); + + this._map = options.map; + this._olMap = options.map.olMap; + this._popupContainers = []; + this._popupOverlays = []; + this._handlers = []; + + this.appManager = options.appManager; + this.mode = options.mode || "single"; + }, + /** + */ + createPopupContent: function (groupWidgets) { + var contentWidget = new ContentPane(); + groupWidgets.forEach(function (groupWidget) { + if (groupWidget && !groupWidget.isEmpty()) { + contentWidget.addChild(groupWidget); + } + }); + return contentWidget; + }, + + /** + * Возвращает обещание на получение объекта с результатом идентификации + * по всем видимым режимам и информационным слоям @ options {Object} @ pixel + * {Object} - информация о точке идентификации @ coordinate {Array} - + * координаты точки иденификации + */ + getGroupsFromVisibleModules: function (options) { + var promises = []; + var modules = this.appManager.getVisibleModules(); + modules.forEach(function (module) { + promises.push.apply(promises, module + .getIdentifyResult(options)); + }); + + return promiseAll(promises).then( + function (results) { + console.log("promise all groups = ", results); + return results; + }); + }, + + identifyPosition: function (position) { + var me = this, i; + var popupContainer = null, + popupOverlay = null; + if (me.mode == "multiple") { + // TODO: создать popupContainer и popupOverlay + popupContainer = new PopupContainer({ + map: me._olMap + }); + on(popupContainer, "close", function () { + var index = me._popupContainers.indexOf(me); + me._popupContainers.splice(index, 1); + + }); + me._popupContainers.push(popupContainer); + + popupOverlay = new ol.Overlay({ + element: popupContainer.domNode, + autoPan: true, + autoPanAnimation: { + duration: 250 + } + }); + me._popupOverlays.push(popupOverlay); + me._olMap.addOverlay(popupOverlay); + + } else { + if (me._popupContainers.length > 0) { + // Берем первый + popupContainer = me._popupContainers[0]; + // Все остальные удалить + if (me._popupContainers.length > 1) { + for (i = 1; i < me._popupContainers.length; i++) { + me._popupContainers[i].destroyRecursive(); + } + me._popupContainers.splice( + 1, + me._popupContainers.length - 1); + } + } else { + // Создаем новый + popupContainer = new PopupContainer({ + map: me._olMap + }); + on(popupContainer, "close", function () { + var index = me._popupContainers.indexOf(me); + me._popupContainers.splice(index, 1); + + }); + me._popupContainers.push(popupContainer); + } + if (me._popupOverlays.length > 0) { + // Берем первый и помещаем в него popup + popupOverlay = me._popupOverlays[0]; + popupOverlay.setElement(popupContainer.domNode); + // Все остальные удалить + if (me._popupOverlays.length > 1) { + for (i = 1; i < me._popupOverlays.length; i++) { + me._olMap.removeOverlay(me._popupOverlays[i]); + } + me._popupOverlays.splice( + 1, + me._popupOverlays.length - 1) + } + } else { + // Создаем новый и помещаем в него popup + popupOverlay = new ol.Overlay({ + element: popupContainer.domNode, + autoPan: true, + autoPanAnimation: { + duration: 250 + } + }); + me._popupOverlays.push(popupOverlay); + me._olMap.addOverlay(popupOverlay); + } + } + + popupContainer.destroyDescendants(); + + popupOverlay.setPosition(position.coordinate); + + popupContainer.showOverlay(); + + when(me.getGroupsFromVisibleModules(position), function (data) { + var contentWidget = me.createPopupContent(data); + popupContainer.show(contentWidget, "only"); + popupContainer.hideOverlay(); + }); + }, + /** + * Скрыть все popups + */ + hideAllPopups: function () { + var me = this, i; + for (i = 0; i < this._popupContainers.length; i++) { + this._popupContainers[i].destroyRecursive(); + } + this._popupContainers.splice(0, this._popupContainers.length); + + for (i = 0; i < this._popupOverlays.length; i++) { + this._olMap.removeOverlay(this._popupOverlays[i]); + } + this._popupOverlays.splice(0, this._popupOverlays.length) + }, + + onActivating: function () { + var me = this; + // Обработчик для события "singleclick" по карте + var handler = listen(this._olMap, 'singleclick', function (evt) { + if (evt.originalEvent.ctrlKey) { + me.mode = "multiple"; + } else { + me.mode = "single"; + } + me.identifyPosition({ + pixel: evt.pixel, + coordinate: evt.coordinate + }); + }); + this._handlers.push(handler); + }, + + onDeactivating: function () { + var me = this; + me._handlers.forEach(function (handler) { + if (handler.remove) + handler.remove(); + + }); + this.hideAllPopups(); + }, + }) + }); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/IdentifyGroup.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/IdentifyGroup.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,89 @@ +define( + [ + "implab/safe", + 'dijit/_WidgetBase', + 'dijit/_TemplatedMixin', + "dijit/_WidgetsInTemplateMixin", + "dijit/layout/_LayoutWidget", + "dijit/layout/ContentPane", + "dojo/_base/declare", + "dojo/dom-construct", + "dojo/on", + "ol3/IdentifyItem" ], + function( + safe, + _WidgetBase, + _TemplatedMixin, + _WidgetsInTemplateMixin, + _LayoutWidget, + ContentPane, + declare, + domConstruct, + on, + IdentifyItem) { + + return declare( + [ _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin ], + { + + /** + */ + _empty : true, + /** + */ + layerName : null, + /** + * Шаблон всего widget + */ + templateString : "
+ * { + * extent : ol3.Extent, + * } + *+ */ + query: function (q, options) { + var me = this; + var filter = this.queryEngine(q, options); + + if (this.notify && !this.hasOwnProperty("_subscriptions")) { + me._subscriptions = []; + + var sc = function (evt, handler) { + me._subscriptions.push(listen(me._source, evt, safe.delegate(me, handler))); + } + + sc("addfeature", "_onAdd"); + sc("changefeature", "_onUpdate"); + sc("removefeature", "_onRemove"); + } + + var predicate, data, extent = filter.matches && + filter.matches.extent; + // если это запрос с указанием области + if (extent) { + predicate = filter.matches.predicate; + + data = this._source.getFeaturesInExtent(extent); + + if (predicate) + data = array.filter(data, predicate); + + if (filter.sort) + filter.sort(data); + + if (filter.paginate) + data = filter.paginate(data); + } else { + // любой другой запрос + data = filter(this._source.getFeatures()); + } + + return new QueryResults(data); + }, + + put: function (obj, options) { + safe.argumentOfType(obj, ol.Feature, "obj"); + if (!options) + options = {}; + + if (options.id) + obj.setId(options.id); + + var id = obj.getId() || new UUID(); + + var prev = this.get(id); + + if ('overwrite' in options) { + // overwrite=true указан, но перезаписывать нечего + if (!prev && options.overwrite) + throw new Error("The specified feature with id '" + + id + "' doesn't exist in the store"); + + // overwrite=false указан, но объект уже существует + if (prev && !options.overwrite) + throw new Error("The specified feature with id '" + + id + "' already exists in the store"); + } + + // ok + if (prev) { + var data = obj.getProperties(); + prev.setProperties(data); + } else { + this._source.addFeature(obj); + } + + return id; + }, + + add: function (obj, options) { + safe.argumentOfType(obj, ol.Feature, "obj"); + + if (!options) + options = {}; + + if (options.id) + obj.setId(options.id); + + var id = obj.getId() || new UUID(); + + var prev = this.get(id); + + if (prev) + throw new Error("The specified feature with id '" + id + + "' already exists in the store"); + + this._source.addFeature(obj); + }, + + remove: function (id) { + var me = this; + + var ft = me.get(id); + if (ft) + me._source.removeFeature(ft); + }, + + getIdentity: function (obj) { + if (safe.isNull(obj)) + return undefined; + if (!(obj instanceof ol.Feature)) + throw new Error("A feature is expected"); + + return obj.getId(); + }, + + _onAdd: function (ev) { + this.notify(ev.feature); + }, + + _onRemove: function (ev) { + var id = ev.feature.getId(); + if (!safe.isNull(id)) + this.notify(undefined, id); + }, + + _onUpdate: function (ev) { + var id = ev.feature.getId(); + if (!safe.isNull(id)) + this.notify(ev.feature, id); + }, + + dispose: function () { + var me = this; + if (me._subscriptions) + me._subscriptions.forEach(function (sc) { + sc.remove(); + }); + + me._source = null; + me._subscriptions = null; + } + }); + }); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/VectorStoreQuery.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/VectorStoreQuery.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,67 @@ +define([ "ol" ], function(ol) { + + function buildFilter(filter) { + if (filter instanceof Function) + return filter; + if (filter) { + var match = function(str) { + return { + test : function(x) { + if (x === null || x === undefined) + return false; + return x.toString().startsWith(str); + } + }; + }; + + for ( var p in filter) { + if (typeof (filter[p]) == "string" && filter[p].endsWith("*")) + filter[p] = match(filter[p].substr(0, filter[p].length)); + } + return function(ft) { + for ( var p in filter) { + if (filter[p] && filter[p].test ? !filter[p] + .test(ft.get(p)) : ft.get(p) != filter[p]) + return false; + } + return true; + }; + } + throw new Error("Unsupported filter"); + } + + /** + * @constructor + * @example + * + *
+ * var store = new VectorStore({ + * source : vectorSource + * }); + * + * var req = new VectorStoreQuery({ + * city : "Moscow" + * }, [ 30, 50, 40, 60 ]); + * + * store.query(req).then(showResults); + *+ */ + return function(filter, extent) { + var match = filter && buildFilter(filter); + + var query = function(ft) { + if (extent) { + var g = gt.getGeometry(); + if (!g || !ol.extent.intersects(extent, g.getExtent())) + return false; + } + + return !match || match(ft); + }; + + query.extent = extent; + query.predicate = match; + + return query; + }; +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/WFSSource.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/WFSSource.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,112 @@ +define([ "ol", "dojo/request", "dojo/_base/array", "implab/safe"], + +function(ol, request, array, safe) { + return function(wfs, featurePrefix, featureType, featureNS, queryArgs) { + if (arguments.length == 1) { + featurePrefix = wfs.featurePrefix; + featureType = wfs.featureType; + featureNS = wfs.featureNS; + wfs = wfs.wfsURL; + queryArgs = wfs.queryArgs; + } + + safe.argumentNotNull(wfs, "wfsURL"); + safe.argumentNotEmpty(featurePrefix, "featurePrefix"); + safe.argumentNotEmpty(featureNS, "featureNS"); + safe.argumentNotEmpty(featureType, "featureType"); + + var format = new ol.format.WFS({ + featureNS : featureNS, + featureType : featureType + }); + + var layerName = featurePrefix + ":" + featureType; + + function loader(extent, resolution, projection) { + var query = { + service : 'WFS', + version : '1.1.0', + request : 'GetFeature', + typename : layerName, + srsname : projection.getCode() + }; + safe.mixin(query, queryArgs); + + if (extent && isFinite(extent[0])) + query.bbox = extent.join(',') + "," + projection.getCode(); + + return request(wfs, { + query : query, + handleAs : 'xml' + }).then(function(data) { + // в загрузчике нельзя вызывать метод source.clear() поскольку + // это приводит к рекурсии + var features = format.readFeatures(data); + + var map = {}, del = [], add = []; + + array.forEach(features, function(x) { + // HACK исправляем идентификаторы, чтобы они совпадали с + // реальными + + var id = x.get("id"); + if (id) + x.setId(id); + else + id = x.getId(); + + map[id] = x; + + // нужно проверить, была ли фича на карте + var prev = source.getFeatureById(id); + if (prev) { + // если да, то обновить ее. + var data = x.getProperties(); + prev.setProperties(data); + } else { + // иначе добавить + add.push(x); + } + }); + + source.forEachFeatureInExtent(extent, function(x) { + if (!(x.getId() in map)) + del.push(x); + }); + + source.addFeatures(add); + + array.forEach(del, function(x) { + source.removeFeature(x); + }); + + //revision = revision + 1; + + source.set("revision", ++revision); + + }); + } + + var cls = ol.source.ServerVector || ol.source.Vector; + var revision = 0; + var source = new cls({ + loader : loader, + //revision: revision + wrapX : false + // , + // strategy : options.strategy || ol.loadingstrategy.all, + // projection : options.projection + }); + source.set("revision", revision); + source.reload = function(extent,resolution, projection, q) { + if (arguments.length >= 4) + queryArgs = q; + if (!extent) + extent = [-Infinity, -Infinity, Infinity, Infinity]; + return loader(extent,resolution,projection); + }; + + console.log(wfs, layerName); + return source; + }; +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/_OneshotTool.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/_OneshotTool.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,65 @@ +define([ "dojo/_base/declare", "implab/safe", "implab/guard", "ol3/_ToolBase", "ol3/ToolType" ], + +function(declare, safe, guard, _ToolBase, ToolType) { + return declare([ _ToolBase ], { + _pending : null, + + _lastResult : null, + + toolType : ToolType.Oneshot, + + invoke : function() { + }, + + onActivating : function() { + var me = this; + + // start the operation + me._lastResult = me._pending = guard(me,"invoke"); + + return this.inherited(arguments); + }, + + onActivated : function() { + var me = this; + + // fire the activate event + this.inherited(arguments); + + me._pending.then(function() { + if (me._pending) { + me.log("Operation finished, deactivating."); + me._pending = null; + me.deactivate(); + } + }, function(ex) { + if (me._pending) { + me.error("Operation failed, deactivating: {0}", ex); + me._pending = null; + me.deactivate(); + } + }); + }, + + onDeactivated : function() { + var d = this._pending; + if (d) { + this.log("Cancelling pending operation"); + this._pending = null; + d.cancel(); + } + + return this.inherited(arguments); + }, + + run : function() { + var me = this; + + return me.activate().then(function(success) { + if (success) + return me._lastResult; + throw new Error("Operation declined"); + }); + } + }); +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/_ToolBase.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/_ToolBase.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,46 @@ +define([ + "dojo/_base/declare", + "dojo/when", + "implab/safe", + "implab/guard", + "implab/components/_ActivatableMixin", + "implab/log/_LogMixin", + "dojo/Evented", + "./ToolType" ], + +function(declare, when, safe, guard, _ActivatableMixin, _LogMixin, Evented, ToolType) { + return declare([ _ActivatableMixin, Evented ], { + toolType : ToolType.Activatable, + + module : null, + + constructor : function(opts) { + if (opts) { + if (opts.controller) + this.setController(opts.controller); + } + }, + + onActivating : function() { + var me = this, inherited = this.getInherited(arguments); + if (me.module && !me.module.isActive()) + return me.module.activate().then(function(active) { + return active ? inherited.apply(me) : false; + }); + else + return inherited.apply(me); + }, + + onActivated : function() { + this.emit("active", true); + }, + + onDeactivated : function() { + this.emit("active", false); + }, + + destroy : function() { + + } + }); +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/declare-style.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/declare-style.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,20 @@ +define(["dojo/_base/declare","implab/safe"],function(declare, safe){ + return function(base, proto){ + var cls = declare(base,proto); + + var factory = function() { + var me = this; + cls.apply(me,arguments); + var fn = function() { + return me.getFeatureStyle.apply(me,arguments); + }; + fn.style = me; + fn.styleFunction = fn; + return fn; + }; + + factory.styleClass = cls; + factory.prototype = cls.prototype; + return factory; + }; +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/format/coords.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/format/coords.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,71 @@ +define( + [ "dojo/i18n!./nls/coords", "implab/text/format", "implab/safe" ], + + function(nls, format, safe) { + + var formatDMS = function(coord) { + return formatSD(coord, nls.dmsPattern); + }; + + var formatDM = function(coord) { + return formatSD(coord, nls.dmPattern); + }; + + var formatD = function(coord) { + return formatSD(coord, nls.dPattern); + }; + + /** + * pattern: + * + * {0} - signed floating point number - latitude + * + * {1} - positive floating point number - minutes part of latitude + * + * {2} - positive floating point number - seconds part of latitude + * + * {3} - localized hemisphere sign: north or south + * + * {4} - signed floating point number - longitude + * + * {5} - positive floating point number - minutes part of longitude + * + * {6} - positive floating point number - seconds part of longitude + * + * {7} - localized hemisphere sign: east or west + */ + var formatSD = function(coord, pattern) { + safe.argumentNotNull(coord, "coord"); + if (!pattern) + pattern = nls.sdPattern; + var x = (coord[0] % 360 + 540) % 360 - 180, y = (coord[1] % 180 + 270) % 180 - 90; + + return format(pattern, y, Math.abs((y * 60) % 60), Math + .abs((y * 3600) % 60), y >= 0 ? nls.north : nls.south, x, Math + .abs((x * 60) % 60), Math.abs((x * 3600) % 60), x >= 0 + ? nls.east + : nls.west); + }; + + var cls = function(fmt) { + switch (fmt) { + case "DMS": + return formatDMS; + case "DM": + return formatDM; + case "D": + return formatD; + case "SD": + return formatSD; + default: + if (!fmt) + return formatSD; + else + return function(coord) { + return formatSD(coord, fmt); + } + } + }; + + return cls; + }); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/format/nls/coords.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/format/nls/coords.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,14 @@ +define({ + root : { + // lat lon + dmsPattern : "{0:!00;00}\u00b0{1:!00}\u2032{2:00}\u2033{3} {4:!000;000}\u00b0{5:!00}\u2032{6:00}\u2033{7}", + dmPattern : "{0:!00;00}\u00b0{1:00.0000}\u2032{3} {4:000;000}\u00b0{5:!00.0000}\u2032{7}", + dPattern : "{0:00.000000;00.000000}\u00b0{3} {4:000.000000;000.000000}\u00b0{7}", + sdPattern : "{0:#0.000000}, {4:#0.000000}", + north : "N", + south : "S", + west : "W", + east : "E" + }, + ru : true +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/format/nls/ru/coords.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/format/nls/ru/coords.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,6 @@ +define({ + north : "С", + south : "Ю", + west : "З", + east : "В" +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/format/nls/ru/units.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/format/nls/ru/units.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,11 @@ +define({ + kmph : "км/ч", + mps : "м/с", + knots : "уз", + meters : "м", + kilometers : "км", + meters2 : "м2", + kilometers2 : "км2", + nmiles : "миль", + nmiles2 : "миль2" +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/format/nls/units.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/format/nls/units.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,14 @@ +define({ + root : { + kmph: "km/h", + mps: "m/s", + knots : "kn", + meters : "m", + kilometers : "km", + meters2 : "m2", + kilometers2 : "m2", + nmiles : "nmi", + nmiles2 : "nmi2" + }, + ru : true +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/interaction/FeatureDrag.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/interaction/FeatureDrag.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,123 @@ +define([ "dojo/_base/declare", "ol", "dojo/Evented" ], function(declare, ol, + Evented) { + + var peekFirstFeature = function(map, coordinate, pixel) { + return map.forEachFeatureAtPixel(function(ft, layer) { + return ft; + }); + }; + + var cls = declare([ ol.interaction.Pointer ], { + "-chains-" : { + constructor : "manual" + }, + + _peek : null, + + _feature : null, + + _coordinate : null, + + cursor : "pointer", + + _oldCursor : undefined, + + /** + * Создает новый объект + * + * @param {Object} + * opts опции + * @param {Function} + * opts.peek Функция выбора фичи для перетаскивания + * function(map,coordinate,pixel), возвращает фичу + * @param {String} + * opts.cursor css курсор который будет использован при + * наведении и перетаскивании фичи + * + */ + constructor : function(opts) { + + ol.interaction.Pointer.apply(this, [{ + handleDownEvent : this.handleDownEvent, + handleDragEvent : this.handleDragEvent, + handleMoveEvent : this.handleMoveEvent, + handleUpEvent : this.handleUpEvent + }]); + Evented.apply(this); + + if (opts) { + if (opts.peek) { + this._peek = opts.peek; + } else { + this._peek = peekFirstFeature; + } + if ("cursor" in opts) + this.cursor = opts.cursor; + } + }, + + handleDownEvent : function(evt) { + var c = evt.coordinate; + + var ft = this._peek(evt.map, c, evt.pixel); + + if (ft) { + this._feature = ft; + this._coordinate = c; + this._emit("dragbegin", { feature : ft }); + return true; + } + + return false; + }, + + handleDragEvent : function(evt) { + var c1 = this._coordinate, c2 = evt.coordinate; + + var dx = c2[0] - c1[0]; + var dy = c2[1] - c1[1]; + + this._emit("dragging", { feature : this._feature, fromCoord : c1, toCoord : c2 }); + + this._feature.getGeometry().translate(dx, dy); + + this._coordinate = c2; + }, + + handleUpEvent : function(evt) { + if (this._feature) + this._emit("dragend", { feature : this._feature }); + + this._feature = null; + this._coordinate = null; + return false; + }, + + handleMoveEvent : function(evt) { + if (this.cursor) { + var ft = this._feature || this._peek(evt.map, evt.coordinate , evt.pixel); + + var element = evt.map.getTargetElement(); + if (ft) { + if (element.style.cursor != this.cursor) { + this._oldCursor = element.style.cursor; + element.style.cursor = this.cursor; + } + } else if (this._oldCursor !== undefined) { + element.style.cursor = this._oldCursor; + this._oldCursor = undefined; + } + } + }, + + _emit : function(name, data) { + var evt = new ol.source.VectorEvent(name,this); + + for(var p in data) + evt[p] = data[p]; + this.dispatchEvent(evt); + } + }); + + return cls; +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/listen.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/listen.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,22 @@ +define(["ol"], function(ol) { + + var listen = function(target, event, callback) { + var key = target.on(event, callback); + return { + remove : function() { + ol.Observable.unByKey(key); + } + }; + }; + + listen.once = function(target, event, callback) { + var key = target.once(event, callback); + return { + remove : function() { + ol.Observable.unByKey(key); + } + }; + }; + + return listen; +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/main.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/main.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,6 @@ +define([ "ol" ], function(ol) { + // вспомогательный класс для получения ol в виде зависимости + return function() { + return ol; + }; +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/ol-stub.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/ol-stub.js Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,4 @@ +var ol; +define([], function() { + return ol; +}); \ No newline at end of file diff -r 9c0943c68a90 -r f0035923ff3e src/djol/resources/LayerCheckBoxTemplate.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/djol/resources/LayerCheckBoxTemplate.html Mon Aug 21 17:47:00 2017 +0300 @@ -0,0 +1,4 @@ +