Mercurial > pub > ImplabJs
comparison src/djol/VectorStore.js @ 8:f0035923ff3e
добавлена библиотека для работы с openlayers 3+
| author | cin |
|---|---|
| date | Mon, 21 Aug 2017 17:47:00 +0300 |
| parents | |
| children | 60f6493e2892 |
comparison
equal
deleted
inserted
replaced
| 7:9c0943c68a90 | 8:f0035923ff3e |
|---|---|
| 1 define( | |
| 2 [ | |
| 3 "dojo/_base/declare", | |
| 4 "dojo/_base/array", | |
| 5 "implab/safe", | |
| 6 "implab/Uuid", | |
| 7 "ol", | |
| 8 "ol3/listen", | |
| 9 "./VectorStoreQuery", | |
| 10 "dojo/store/util/QueryResults" | |
| 11 ], | |
| 12 function (declare, array, safe, UUID, ol, listen, VectorStoreQuery, QueryResults) { | |
| 13 function createPaginator(opts) { | |
| 14 return (opts.count || opts.start) && | |
| 15 function (results) { | |
| 16 var total = results.length; | |
| 17 results = results.slice(opts.start || 0, (opts.start || 0) + | |
| 18 (opts.count || Infinity)); | |
| 19 results.total = total; | |
| 20 | |
| 21 return results; | |
| 22 }; | |
| 23 } | |
| 24 | |
| 25 /** | |
| 26 * Обертка вокруг векторного источника данных ol.source.Vector, | |
| 27 * реализует dojo/store а также notify, что делает возможным наблюдение | |
| 28 * за хранилищем при помощи dojo/store/Observable. | |
| 29 * | |
| 30 * @disposable | |
| 31 */ | |
| 32 return declare( | |
| 33 null, { | |
| 34 _source: null, // ol3.source.Vector | |
| 35 | |
| 36 _subscriptions: null, | |
| 37 | |
| 38 constructor: function (opts) { | |
| 39 safe.argumentNotNull(opts, "opts"); | |
| 40 safe.argumentOfType( | |
| 41 opts.source, | |
| 42 ol.source.Vector, | |
| 43 "opts.source"); | |
| 44 | |
| 45 var me = this; | |
| 46 | |
| 47 me._source = opts.source; | |
| 48 }, | |
| 49 | |
| 50 getSource: function () { | |
| 51 return this._source; | |
| 52 }, | |
| 53 | |
| 54 get: function (id) { | |
| 55 return this._source.getFeatureById(id); | |
| 56 }, | |
| 57 | |
| 58 /** | |
| 59 * @param{Object|Function} q предикат для выбора объекта | |
| 60 * @param{Object} opts параметры выполнения (start,count,sort) | |
| 61 * @return{Function} filter(data) filter.matches | |
| 62 * filter.matches.predicate | |
| 63 * filter.matches.extent filter.sort | |
| 64 * filter.sort.compare | |
| 65 */ | |
| 66 queryEngine: function (q, opts) { | |
| 67 opts = opts || {}; | |
| 68 | |
| 69 // строим функцию для фильтрации | |
| 70 var filter; | |
| 71 if (q instanceof Function) { | |
| 72 // если передали уже готовую функцию, испольуем ее | |
| 73 filter = new VectorStoreQuery(q, q.extent); | |
| 74 } else { | |
| 75 // если передали объект | |
| 76 var extent; | |
| 77 // вытаскиваем из него extent | |
| 78 if (q && 'extent' in q) { | |
| 79 extent = q.extent; | |
| 80 delete q.extent; | |
| 81 } | |
| 82 | |
| 83 // строим новую функцию фильтрации | |
| 84 filter = new VectorStoreQuery(q, extent); | |
| 85 } | |
| 86 | |
| 87 // строим функцию сортировки | |
| 88 var sort = opts.sort && this.sortEngine(opts.sort); | |
| 89 | |
| 90 var paginate = createPaginator(opts); | |
| 91 | |
| 92 // строим функцию выполнения запроса | |
| 93 var execute = function (data) { | |
| 94 var results = array.filter(data, filter); | |
| 95 | |
| 96 if (sort) | |
| 97 sort(results); | |
| 98 | |
| 99 if (paginate) | |
| 100 results = paginate(results); | |
| 101 return results; | |
| 102 }; | |
| 103 | |
| 104 execute.matches = filter; | |
| 105 execute.sort = sort; | |
| 106 execute.paginate = paginate; | |
| 107 return execute; | |
| 108 }, | |
| 109 | |
| 110 sortEngine: function (options) { | |
| 111 var cmp = function (a, b) { | |
| 112 for (var sort, i = 0; | |
| 113 (sort = options[i]); i++) { | |
| 114 var aValue = a.get(sort.attribute); | |
| 115 var bValue = b.get(sort.attribute); | |
| 116 if (aValue != bValue) { | |
| 117 return Boolean(sort.descending) == aValue > bValue ? -1 : 1; | |
| 118 } | |
| 119 } | |
| 120 return 0; | |
| 121 }; | |
| 122 | |
| 123 var execute = function (data) { | |
| 124 return data.sort(cmp); | |
| 125 }; | |
| 126 | |
| 127 execute.compare = cmp; | |
| 128 return execute; | |
| 129 }, | |
| 130 | |
| 131 /** | |
| 132 * Запрашивает объекты со слоя | |
| 133 * | |
| 134 * @param{object|VectorStoreQuery|Function} query | |
| 135 * | |
| 136 * <pre> | |
| 137 * { | |
| 138 * extent : ol3.Extent, | |
| 139 * } | |
| 140 * </pre> | |
| 141 */ | |
| 142 query: function (q, options) { | |
| 143 var me = this; | |
| 144 var filter = this.queryEngine(q, options); | |
| 145 | |
| 146 if (this.notify && !this.hasOwnProperty("_subscriptions")) { | |
| 147 me._subscriptions = []; | |
| 148 | |
| 149 var sc = function (evt, handler) { | |
| 150 me._subscriptions.push(listen(me._source, evt, safe.delegate(me, handler))); | |
| 151 } | |
| 152 | |
| 153 sc("addfeature", "_onAdd"); | |
| 154 sc("changefeature", "_onUpdate"); | |
| 155 sc("removefeature", "_onRemove"); | |
| 156 } | |
| 157 | |
| 158 var predicate, data, extent = filter.matches && | |
| 159 filter.matches.extent; | |
| 160 // если это запрос с указанием области | |
| 161 if (extent) { | |
| 162 predicate = filter.matches.predicate; | |
| 163 | |
| 164 data = this._source.getFeaturesInExtent(extent); | |
| 165 | |
| 166 if (predicate) | |
| 167 data = array.filter(data, predicate); | |
| 168 | |
| 169 if (filter.sort) | |
| 170 filter.sort(data); | |
| 171 | |
| 172 if (filter.paginate) | |
| 173 data = filter.paginate(data); | |
| 174 } else { | |
| 175 // любой другой запрос | |
| 176 data = filter(this._source.getFeatures()); | |
| 177 } | |
| 178 | |
| 179 return new QueryResults(data); | |
| 180 }, | |
| 181 | |
| 182 put: function (obj, options) { | |
| 183 safe.argumentOfType(obj, ol.Feature, "obj"); | |
| 184 if (!options) | |
| 185 options = {}; | |
| 186 | |
| 187 if (options.id) | |
| 188 obj.setId(options.id); | |
| 189 | |
| 190 var id = obj.getId() || new UUID(); | |
| 191 | |
| 192 var prev = this.get(id); | |
| 193 | |
| 194 if ('overwrite' in options) { | |
| 195 // overwrite=true указан, но перезаписывать нечего | |
| 196 if (!prev && options.overwrite) | |
| 197 throw new Error("The specified feature with id '" + | |
| 198 id + "' doesn't exist in the store"); | |
| 199 | |
| 200 // overwrite=false указан, но объект уже существует | |
| 201 if (prev && !options.overwrite) | |
| 202 throw new Error("The specified feature with id '" + | |
| 203 id + "' already exists in the store"); | |
| 204 } | |
| 205 | |
| 206 // ok | |
| 207 if (prev) { | |
| 208 var data = obj.getProperties(); | |
| 209 prev.setProperties(data); | |
| 210 } else { | |
| 211 this._source.addFeature(obj); | |
| 212 } | |
| 213 | |
| 214 return id; | |
| 215 }, | |
| 216 | |
| 217 add: function (obj, options) { | |
| 218 safe.argumentOfType(obj, ol.Feature, "obj"); | |
| 219 | |
| 220 if (!options) | |
| 221 options = {}; | |
| 222 | |
| 223 if (options.id) | |
| 224 obj.setId(options.id); | |
| 225 | |
| 226 var id = obj.getId() || new UUID(); | |
| 227 | |
| 228 var prev = this.get(id); | |
| 229 | |
| 230 if (prev) | |
| 231 throw new Error("The specified feature with id '" + id + | |
| 232 "' already exists in the store"); | |
| 233 | |
| 234 this._source.addFeature(obj); | |
| 235 }, | |
| 236 | |
| 237 remove: function (id) { | |
| 238 var me = this; | |
| 239 | |
| 240 var ft = me.get(id); | |
| 241 if (ft) | |
| 242 me._source.removeFeature(ft); | |
| 243 }, | |
| 244 | |
| 245 getIdentity: function (obj) { | |
| 246 if (safe.isNull(obj)) | |
| 247 return undefined; | |
| 248 if (!(obj instanceof ol.Feature)) | |
| 249 throw new Error("A feature is expected"); | |
| 250 | |
| 251 return obj.getId(); | |
| 252 }, | |
| 253 | |
| 254 _onAdd: function (ev) { | |
| 255 this.notify(ev.feature); | |
| 256 }, | |
| 257 | |
| 258 _onRemove: function (ev) { | |
| 259 var id = ev.feature.getId(); | |
| 260 if (!safe.isNull(id)) | |
| 261 this.notify(undefined, id); | |
| 262 }, | |
| 263 | |
| 264 _onUpdate: function (ev) { | |
| 265 var id = ev.feature.getId(); | |
| 266 if (!safe.isNull(id)) | |
| 267 this.notify(ev.feature, id); | |
| 268 }, | |
| 269 | |
| 270 dispose: function () { | |
| 271 var me = this; | |
| 272 if (me._subscriptions) | |
| 273 me._subscriptions.forEach(function (sc) { | |
| 274 sc.remove(); | |
| 275 }); | |
| 276 | |
| 277 me._source = null; | |
| 278 me._subscriptions = null; | |
| 279 } | |
| 280 }); | |
| 281 }); |
