1 | geolib = require 'geolib'
|
2 | csv = require 'fast-csv'
|
3 |
|
4 | MapPLZ = ->
|
5 |
|
6 | MapPLZ.standardize = (geo, props) ->
|
7 | result = new MapItem
|
8 | if typeof geo.lat != "undefined" && typeof geo.lng != "undefined"
|
9 | result.lat = geo.lat * 1
|
10 | result.lng = geo.lng * 1
|
11 | else if geo.path
|
12 | result.path = geo.path
|
13 | result.properties = props || {}
|
14 | result
|
15 |
|
16 | MapPLZ.prototype.add = (param1, param2, param3, param4) ->
|
17 | this.mapitems = [] unless this.mapitems
|
18 | this.database = null unless this.database
|
19 |
|
20 | callback = (err, items) ->
|
21 | callback = param2 if typeof param2 == "function"
|
22 | callback = param3 if typeof param3 == "function"
|
23 | callback = param4 if typeof param4 == "function"
|
24 |
|
25 |
|
26 | lat = param1 * 1
|
27 | lng = param2 * 1
|
28 | unless isNaN(lat) || isNaN(lng)
|
29 | pt = MapPLZ.standardize({ lat: lat, lng: lng })
|
30 | pt.type = "point"
|
31 |
|
32 | if param3 != null
|
33 |
|
34 | if typeof param3 == 'string'
|
35 | try
|
36 | pt.properties = JSON.parse param3
|
37 | catch
|
38 |
|
39 | if this.isArray param3
|
40 |
|
41 | pt.properties = { property: param3 }
|
42 | else if typeof param3 == 'object'
|
43 |
|
44 | for key in Object.keys(param3)
|
45 | pt.properties[key] = param3[key]
|
46 | else if typeof param3 != 'function'
|
47 |
|
48 | pt.properties = { property: param3 }
|
49 |
|
50 | this.save pt, callback
|
51 | return
|
52 |
|
53 | if typeof param1 == 'string'
|
54 |
|
55 | try
|
56 | param1 = JSON.parse param1
|
57 | if this.isGeoJson param1
|
58 | result = this.addGeoJson param1, callback
|
59 | this.save result, callback if result
|
60 | return
|
61 | catch
|
62 | if param1[param1.length-1] == ')' && (param1.indexOf 'POINT' == 0 || param1.indexOf 'LINESTRING' == 0 || param1.indexOf 'POLYGON' == 0)
|
63 |
|
64 | contents = ''
|
65 | if param1.indexOf('POINT') == 0
|
66 | contents = param1.replace('POINT', '').replace('(', '').replace(')', '').trim().split(' ').reverse()
|
67 | else if param1.indexOf('LINESTRING') == 0
|
68 | pts = param1.replace('LINESTRING', '').replace('(', '').replace(')', '').split(',')
|
69 | contents = []
|
70 | for pt in pts
|
71 | contents.push pt.trim().split(' ').reverse()
|
72 | else if param1.indexOf('POLYGON') == 0
|
73 | pts = param1.replace('POLYGON', '').replace('(', '').replace(')', '').replace('(', '').replace(')', '').split(',')
|
74 | contents = []
|
75 | for pt in pts
|
76 | contents.push pt.trim().split(' ').reverse()
|
77 |
|
78 | this.add contents, param2 || callback, callback
|
79 | return
|
80 |
|
81 | if (param1.indexOf('map') > -1) and (param1.indexOf('plz') > -1)
|
82 |
|
83 | this.process_code param1, callback
|
84 | return
|
85 |
|
86 | else
|
87 |
|
88 | callbacks = 0
|
89 | contents = []
|
90 | mapstore = this
|
91 |
|
92 | records = 0
|
93 | finished = false
|
94 |
|
95 | csv.fromString(param1, { headers: true })
|
96 | .on('record', (data) ->
|
97 | records++
|
98 | if data.geo || data.geom || data.wkt
|
99 | mapstore.add (data.geo || data.geom || data.wkt), data, (err, item) ->
|
100 | contents.push item unless err
|
101 | callback(err, contents) if finished && contents.length == records
|
102 | else
|
103 | mapstore.add data, (err, item) ->
|
104 | contents.push item unless err
|
105 | callback(err, contents) if finished && contents.length == records
|
106 | )
|
107 | .on('end', ->
|
108 | finished = true
|
109 | callback(null, contents) if contents.length == records
|
110 | )
|
111 | return
|
112 |
|
113 | if this.isArray param1
|
114 |
|
115 |
|
116 | if param1.length >= 2
|
117 | lat = param1[0] * 1
|
118 | lng = param1[1] * 1
|
119 | unless isNaN(lat) || isNaN(lng)
|
120 | result = MapPLZ.standardize { lat: lat, lng: lng }
|
121 | result.type = 'point'
|
122 | for prop in param1.slice(2)
|
123 | if typeof prop == 'string'
|
124 | try
|
125 | prop = JSON.parse prop
|
126 | catch
|
127 | prop = prop
|
128 |
|
129 | if typeof prop == 'object'
|
130 | for key in Object.keys(prop)
|
131 | result.properties[key] = prop[key]
|
132 | else if typeof prop != 'function'
|
133 | result.properties = { property: prop }
|
134 |
|
135 | this.save result, callback
|
136 | return
|
137 |
|
138 | if typeof param1[0] == 'object'
|
139 | if this.isArray param1[0]
|
140 |
|
141 | if this.isArray param1[0][0]
|
142 |
|
143 | result = MapPLZ.standardize({ path: param1 })
|
144 | result.type = 'polygon'
|
145 | else
|
146 |
|
147 | result = MapPLZ.standardize({ path: param1 })
|
148 | result.type = 'line'
|
149 |
|
150 | if result && param2
|
151 |
|
152 | if typeof param2 == 'string'
|
153 | try
|
154 | param2 = JSON.parse param2
|
155 | catch
|
156 | param2 = param2
|
157 |
|
158 | if typeof param2 == 'object'
|
159 | if this.isArray param2
|
160 | result.properties = { property: param2 }
|
161 | else
|
162 | result.properties = param2
|
163 | else if typeof param2 != 'function'
|
164 | result.properties = { property: param2 }
|
165 |
|
166 | this.save result, callback
|
167 | return
|
168 | else
|
169 |
|
170 | results = []
|
171 | for obj in param1
|
172 | results.push this.add(obj)
|
173 | this.save results, callback
|
174 | return
|
175 |
|
176 |
|
177 | else if typeof param1 == 'object'
|
178 |
|
179 | if param1.lat && param1.lng
|
180 | result = MapPLZ.standardize({ lat: param1.lat, lng: param1.lng })
|
181 | result.type = "point"
|
182 | for key in Object.keys(param1)
|
183 | result.properties[key] = param1[key] unless key == 'lat' || key == 'lng'
|
184 | this.save result, callback
|
185 | return
|
186 |
|
187 | else if param1.path
|
188 | result = MapPLZ.standardize({ path: param1.path })
|
189 | if typeof param1.path[0][0] == 'object'
|
190 | result.type = 'polygon'
|
191 | else
|
192 | result.type = 'line'
|
193 | for key in Object.keys(param1)
|
194 | result.properties[key] = param1[key] unless key == 'path'
|
195 |
|
196 | this.save result, callback
|
197 | return
|
198 |
|
199 | else if this.isGeoJson param1
|
200 | results = this.addGeoJson param1, callback
|
201 | this.save results, callback if results
|
202 | return
|
203 |
|
204 | MapPLZ.prototype.count = (query, callback) ->
|
205 | if this.database
|
206 | this.database.count(query, callback)
|
207 | else
|
208 | this.query query, (err, results) ->
|
209 | callback(err, results.length)
|
210 |
|
211 | MapPLZ.prototype.query = (query, callback) ->
|
212 | if this.database
|
213 | this.database.query(query, callback)
|
214 | else
|
215 | if query == null || query == ""
|
216 | callback(null, this.mapitems)
|
217 | else
|
218 | results = []
|
219 | for mapitem in this.mapitems
|
220 | if mapitem && mapitem.type != "deleted"
|
221 | match = true
|
222 | for key of query
|
223 | match = (mapitem.properties[key] == query[key])
|
224 | break unless match
|
225 | results.push mapitem if match
|
226 | callback(null, results)
|
227 |
|
228 | MapPLZ.prototype.where = (query, callback) ->
|
229 | this.query(query, callback)
|
230 |
|
231 | MapPLZ.prototype.near = (neargeo, count, callback) ->
|
232 | nearpt = neargeo
|
233 | if this.isArray(neargeo)
|
234 | nearpt = new MapItem
|
235 | nearpt.type = "point"
|
236 | nearpt.lat = neargeo[0]
|
237 | nearpt.lng = neargeo[1]
|
238 | else
|
239 | if typeof neargeo == 'string'
|
240 | neargeo = JSON.parse(neargeo)
|
241 | unless typeof neargeo.lat == "undefined" && typeof neargeo.lng == "undefined"
|
242 | nearpt = this.addGeoJson(neargeo)
|
243 |
|
244 | if this.database
|
245 | this.database.near(nearpt, count, callback)
|
246 | else
|
247 | this.query "", (err, items) ->
|
248 | centerpts = []
|
249 | for item in items
|
250 | center = item.center()
|
251 | centerpts.push { latitude: center.lat, longitude: center.lng }
|
252 | centerpts = geolib.orderByDistance({ latitude: nearpt.lat, longitude: nearpt.lng }, centerpts)
|
253 | for pt, p in centerpts
|
254 | centerpts[p] = items[p]
|
255 | break if p >= count
|
256 | callback(null, centerpts.slice(0, count))
|
257 |
|
258 | MapPLZ.prototype.inside = (withingeo, callback) ->
|
259 | withinpoly = withingeo
|
260 | if this.isArray(withingeo)
|
261 | withinpoly = new MapItem
|
262 | withinpoly.type = "polygon"
|
263 | withinpoly.path = withingeo
|
264 | else
|
265 | if typeof withingeo == 'string'
|
266 | withingeo = JSON.parse(withingeo)
|
267 | unless withingeo.path
|
268 | withinpoly = this.addGeoJson(withingeo)
|
269 |
|
270 | if this.database
|
271 | this.database.inside(withinpoly, callback)
|
272 | else
|
273 | this.query "", (err, items) ->
|
274 | withinpoly = withinpoly.path[0]
|
275 | for pt, p in withinpoly
|
276 | withinpoly[p] = { latitude: pt[0], longitude: pt[1] }
|
277 | results = []
|
278 | for item in items
|
279 | center = item.center()
|
280 | if geolib.isPointInside({ latitude: center.lat, longitude: center.lng }, withinpoly)
|
281 | results.push item
|
282 | callback(null, results)
|
283 |
|
284 | MapPLZ.prototype.save = (items, callback) ->
|
285 | if this.database
|
286 | if this.isArray(items)
|
287 | for item in items
|
288 | item.database = this.database
|
289 | item.save(callback)
|
290 | else
|
291 | items.database = this.database
|
292 | items.save(callback)
|
293 | else
|
294 | if this.isArray(items)
|
295 | for item in items
|
296 | item.mapitems = this.mapitems
|
297 | this.mapitems.concat items
|
298 | else
|
299 | items.mapitems = this.mapitems
|
300 | this.mapitems.push items
|
301 | callback(null, items)
|
302 |
|
303 | MapPLZ.prototype.isArray = (inspect) ->
|
304 | return (typeof inspect == 'object' && typeof inspect.push == 'function')
|
305 |
|
306 | MapPLZ.prototype.isGeoJson = (json) ->
|
307 | type = json.type
|
308 | return (type && (type == "Feature" || type == "FeatureCollection"))
|
309 |
|
310 | MapPLZ.prototype.addGeoJson = (gj, callback) ->
|
311 | if gj.type == "FeatureCollection"
|
312 | results = []
|
313 | that = this
|
314 | iter_callback = (feature_index) ->
|
315 | if feature_index < gj.features.length
|
316 | feature = that.addGeoJson(gj.features[feature_index])
|
317 | that.save feature, (err, saved) ->
|
318 | results.push saved
|
319 | iter_callback(feature_index + 1)
|
320 | else
|
321 | callback(null, results)
|
322 | iter_callback(0)
|
323 |
|
324 | else if gj.type == "Feature"
|
325 | geom = gj.geometry
|
326 | result = ""
|
327 | if geom.type == "Point"
|
328 | result = MapPLZ.standardize({ lat: geom.coordinates[1], lng: geom.coordinates[0] })
|
329 | result.type = "point"
|
330 | else if geom.type == "LineString"
|
331 | result = MapPLZ.standardize({ path: this.reverse_path(geom.coordinates) })
|
332 | result.type = "line"
|
333 | else if geom.type == "Polygon"
|
334 | result = MapPLZ.standardize({ path: [this.reverse_path(geom.coordinates[0])] })
|
335 | result.type = "polygon"
|
336 |
|
337 | result.properties = gj.properties || {}
|
338 | result
|
339 |
|
340 | MapPLZ.prototype.process_code = (code, callback) ->
|
341 | code_lines = code.split("\n")
|
342 | code_level = "toplevel"
|
343 | button_layers = []
|
344 | code_button = 0
|
345 | code_layers = []
|
346 | code_label = ""
|
347 | code_color = null
|
348 | code_latlngs = []
|
349 |
|
350 | finish_add = ->
|
351 | added = 0
|
352 | for item in code_layers
|
353 | item.database = this.database
|
354 | item.save (err) ->
|
355 | added++
|
356 | callback(err, code_layers) if code_layers.length == added
|
357 |
|
358 | code_line = (index) ->
|
359 | if index >= code_lines.length
|
360 | return finish_add()
|
361 |
|
362 | line = code_lines[index].trim()
|
363 | codeline = line.toLowerCase().split(' ')
|
364 |
|
365 | if code_level == 'toplevel'
|
366 | code_level = 'map' if line.indexOf('map') > -1
|
367 | return code_line(index + 1)
|
368 |
|
369 | else if code_level == 'map' || code_level == 'button'
|
370 | if codeline.indexOf('button') > -1 || codeline.indexOf('btn') > -1
|
371 | code_level = 'button'
|
372 | button_layers.push { layers: [] }
|
373 | code_button = button_layers.length
|
374 |
|
375 | if codeline.indexOf('marker') > -1
|
376 | code_level = 'marker'
|
377 | code_latlngs = []
|
378 | return code_line(index + 1)
|
379 |
|
380 | else if codeline.indexOf('line') > -1
|
381 | code_level = 'line'
|
382 | code_latlngs = []
|
383 | return code_line(index + 1)
|
384 |
|
385 | else if codeline.indexOf('shape') > -1
|
386 | code_level = 'shape'
|
387 | code_latlngs = []
|
388 | return code_line(index + 1)
|
389 |
|
390 | if codeline.indexOf('plz') > -1 || codeline.indexOf('please') > -1
|
391 | if code_level == 'map'
|
392 | code_level = 'toplevel'
|
393 | return finish_add()
|
394 |
|
395 | else if code_level == 'button'
|
396 |
|
397 | code_level = 'map'
|
398 | code_button = nil
|
399 | return code_line(index + 1)
|
400 |
|
401 | else if code_level == 'marker' || code_level == 'line' || code_level == 'shape'
|
402 | if codeline.indexOf('plz') > -1 || codeline.indexOf('please') > -1
|
403 |
|
404 | if code_level == 'marker'
|
405 | geoitem = new MapItem
|
406 | geoitem.lat = code_latlngs[0][0]
|
407 | geoitem.lng = code_latlngs[0][1]
|
408 | geoitem.properties = { label: (code_label || '') }
|
409 | code_layers.push geoitem
|
410 |
|
411 | else if code_level == 'line'
|
412 | geoitem = new MapItem
|
413 | geoitem.path = code_latlngs
|
414 | geoitem.properties = {
|
415 | color: (code_color || ''),
|
416 | label: (code_label || '')
|
417 | }
|
418 | code_layers.push geoitem
|
419 |
|
420 | else if code_level == 'shape'
|
421 | geoitem = new MapItem
|
422 | geoitem.path = [code_latlngs]
|
423 | geoitem.properties = {
|
424 | color: (code_color || ''),
|
425 | fill_color: (code_color || ''),
|
426 | label: (code_label || '')
|
427 | }
|
428 | code_layers.push geoitem
|
429 |
|
430 | if code_button
|
431 | code_level = 'button'
|
432 | else
|
433 | code_level = 'map'
|
434 |
|
435 | code_latlngs = []
|
436 | return code_line(index + 1)
|
437 |
|
438 |
|
439 |
|
440 |
|
441 | if codeline[0].indexOf('#') == 0
|
442 | code_color = codeline.trim()
|
443 | if code_color.length != 4 && code_color.length != 7
|
444 |
|
445 | code_color = code_color.replace('#', '')
|
446 |
|
447 | return code_line(index + 1)
|
448 |
|
449 |
|
450 | if codeline[0].indexOf('"') == 0
|
451 |
|
452 | code_label = line.substring( line.indexOf('"') + 1 )
|
453 | code_label = code_label.substring(0, code_label.indexOf('"') - 1)
|
454 |
|
455 |
|
456 | if line.indexOf('[') > -1 && line.indexOf(',') > -1 && line.indexOf(']') > -1
|
457 | latlng_line = line.replace('[', '').replace(']', '').split(',')
|
458 | latlng_line[0] *= 1
|
459 | latlng_line[1] *= 1
|
460 |
|
461 |
|
462 | return code_line(index + 1) if latlng_line.length != 2
|
463 |
|
464 | code_latlngs.push latlng_line
|
465 |
|
466 | return code_line(index + 1)
|
467 |
|
468 | code_line(index + 1)
|
469 | code_line(0)
|
470 |
|
471 | MapPLZ.reverse_path = (path) ->
|
472 | path_pts = path.slice(0)
|
473 | for p, pt in path_pts
|
474 | path_pts[pt] = path_pts[pt].slice(0).reverse()
|
475 | path_pts
|
476 |
|
477 |
|
478 |
|
479 | MapItem = ->
|
480 | MapItem.prototype.toGeoJson = ->
|
481 | if this.type == "point"
|
482 | gj_geo = { type: "Point", coordinates: [this.lng, this.lat] }
|
483 | else if this.type == "line"
|
484 | linepath = MapPLZ.reverse_path(this.path)
|
485 | gj_geo = { type: "LineString", coordinates: linepath }
|
486 | else if this.type == 'polygon'
|
487 | polypath = [MapPLZ.reverse_path(this.path[0])]
|
488 | gj_geo = { type: "Polygon", coordinates: polypath }
|
489 | JSON.stringify { type: "Feature", geometry: gj_geo, properties: this.properties }
|
490 |
|
491 | MapItem.prototype.toWKT = ->
|
492 | if this.type == "point"
|
493 | "POINT(#{this.lng} #{this.lat})"
|
494 | else if this.type == "line"
|
495 | linepath = MapPLZ.reverse_path(this.path)
|
496 | for p, pt in linepath
|
497 | linepath[pt] = linepath[pt].join ' '
|
498 | linepath = linepath.join ', '
|
499 | "LINESTRING(#{linepath})"
|
500 | else if this.type == 'polygon'
|
501 | polypath = MapPLZ.reverse_path(this.path[0])
|
502 | for p, pt in polypath
|
503 | polypath[pt] = polypath[pt].join ' '
|
504 | polypath = polypath.join ', '
|
505 | "POLYGON((#{polypath}))"
|
506 |
|
507 | MapItem.prototype.save = (callback) ->
|
508 | if this.database
|
509 | my_mapitem = this
|
510 | this.database.save this, (err, id) ->
|
511 | my_mapitem.id = id if id
|
512 | callback(err, my_mapitem)
|
513 | else
|
514 | callback(null, this)
|
515 |
|
516 | MapItem.prototype.delete = (callback) ->
|
517 | if this.database
|
518 | my_mapitem = this
|
519 | this.database.delete this, (err) ->
|
520 | callback(err)
|
521 | else
|
522 | if this.mapitems.indexOf(this) > -1
|
523 | this.mapitems.splice(this.mapitems.indexOf(this), 1)
|
524 | this.type = "deleted"
|
525 | callback(null)
|
526 |
|
527 | MapItem.prototype.center = ->
|
528 | if this.type == "point"
|
529 | { lat: this.lat, lng: this.lng }
|
530 | else if this.type == "line"
|
531 | avg = { lat: 0, lng: 0 }
|
532 | for pt in this.path
|
533 | avg.lat += pt[0]
|
534 | avg.lng += pt[1]
|
535 | avg.lat /= this.path.length
|
536 | avg.lng /= this.path.length
|
537 | avg
|
538 | else if this.type == "polygon"
|
539 | avg = { lat: 0, lng: 0 }
|
540 | for pt in this.path[0]
|
541 | avg.lat += pt[0]
|
542 | avg.lng += pt[1]
|
543 | avg.lat /= this.path[0].length
|
544 | avg.lng /= this.path[0].length
|
545 | avg
|
546 |
|
547 |
|
548 |
|
549 |
|
550 |
|
551 |
|
552 | PostGIS = ->
|
553 | PostGIS.prototype.save = (item, callback) ->
|
554 | if item.id
|
555 | this.client.query "UPDATE mapplz SET geom = ST_GeomFromText('#{item.toWKT()}'), properties = '#{JSON.stringify(item.properties)}' WHERE id = #{item.id * 1}", (err, result) ->
|
556 | console.error err if err
|
557 | callback(err, item.id)
|
558 | else
|
559 | this.client.query "INSERT INTO mapplz (properties, geom) VALUES ('#{JSON.stringify(item.properties)}', ST_GeomFromText('#{item.toWKT()}')) RETURNING id", (err, result) ->
|
560 | console.error err if err
|
561 | callback(err, result.rows[0].id || null)
|
562 |
|
563 | PostGIS.prototype.delete = (item, callback) ->
|
564 | this.client.query "DELETE FROM mapplz WHERE id = #{item.id * 1}", (err) ->
|
565 | item = null
|
566 | callback(err)
|
567 |
|
568 | PostGIS.prototype.count = (query, callback) ->
|
569 | condition = "1=1"
|
570 | if query && query.length
|
571 | condition = query
|
572 | where_prop = condition.trim().split(' ')[0]
|
573 | condition = condition.replace(where_prop, "json_extract_path_text(properties, '#{where_prop}')")
|
574 |
|
575 | this.client.query "SELECT COUNT(*) AS count FROM mapplz WHERE #{condition}", (err, result) ->
|
576 | callback(err, result.rows[0].count || null)
|
577 |
|
578 | PostGIS.prototype.processResults = (err, db, result, callback) ->
|
579 | if err
|
580 | console.error err
|
581 | callback(err, [])
|
582 | else
|
583 | results = []
|
584 | for row in result.rows
|
585 | geo = JSON.parse(row.geo)
|
586 | result = MapPLZ.prototype.addGeoJson { type: "Feature", geometry: geo, properties: row.properties }
|
587 | result.id = row.id
|
588 | result.database = db
|
589 | results.push result
|
590 | callback(err, results)
|
591 |
|
592 | PostGIS.prototype.query = (query, callback) ->
|
593 | condition = "1=1"
|
594 | db = this
|
595 | if query && query.length
|
596 | condition = query
|
597 | where_prop = condition.trim().split(' ')[0]
|
598 | condition = condition.replace(where_prop, "json_extract_path_text(properties, '#{where_prop}')")
|
599 |
|
600 | this.client.query "SELECT ST_AsGeoJSON(geom) AS geo, properties FROM mapplz WHERE #{condition}", (err, result) ->
|
601 | db.processResults(err, db, result, callback)
|
602 |
|
603 | PostGIS.prototype.near = (nearpt, count, callback) ->
|
604 | db = this
|
605 | this.client.query "SELECT id, ST_AsGeoJSON(geom) AS geo, properties, ST_Distance(start.geom::geography, ST_GeomFromText('#{nearpt.toWKT()}')::geography) AS distance FROM mapplz AS start ORDER BY distance LIMIT #{count}", (err, results) ->
|
606 | db.processResults(err, db, results, callback)
|
607 |
|
608 | PostGIS.prototype.inside = (withinpoly, callback) ->
|
609 | db = this
|
610 | this.client.query "SELECT id, ST_AsGeoJSON(geom) AS geo, properties FROM mapplz AS start WHERE ST_Contains(ST_GeomFromText('#{withinpoly.toWKT()}'), start.geom)", (err, results) ->
|
611 | db.processResults(err, db, results, callback)
|
612 |
|
613 |
|
614 |
|
615 | MongoDB = ->
|
616 | MongoDB.prototype.save = (item, callback) ->
|
617 | saveobj = {}
|
618 | saveobj = JSON.parse(JSON.stringify(item.properties)) if item.properties
|
619 | saveobj.geo = JSON.parse(item.toGeoJson()).geometry
|
620 | if item.id
|
621 | saveobj._id = item.id
|
622 | this.collection.save saveobj, (err) ->
|
623 | console.error err if err
|
624 | callback(err, item.id)
|
625 | else
|
626 | this.collection.insert saveobj, (err, results) ->
|
627 | console.error err if err
|
628 | result = results[0] || null
|
629 | callback(err, result._id || null)
|
630 |
|
631 | MongoDB.prototype.delete = (item, callback) ->
|
632 | this.collection.remove { _id: item.id }, (err) ->
|
633 | item = null
|
634 | callback(err)
|
635 |
|
636 | MongoDB.prototype.count = (query, callback) ->
|
637 | condition = query || {}
|
638 | this.collection.find query, (err, cursor) ->
|
639 | if err
|
640 | console.error err
|
641 | callback(err, null)
|
642 | else
|
643 | cursor.count (err, count) ->
|
644 | callback(err, count || 0)
|
645 |
|
646 | MongoDB.prototype.query = (query, callback) ->
|
647 | condition = query || {}
|
648 | db = this
|
649 | this.collection.find(query).toArray (err, rows) ->
|
650 | if err
|
651 | console.error err
|
652 | callback(err, [])
|
653 | else
|
654 | results = []
|
655 | for row in rows
|
656 | excluded = {}
|
657 | for key of row
|
658 | if key != "_id" && key != "geom"
|
659 | excluded[key] = row[key]
|
660 | result = MapPLZ.prototype.addGeoJson { type: "Feature", geometry: row.geo, properties: excluded }
|
661 | result.id = row._id
|
662 | result.database = db
|
663 | results.push result
|
664 | callback(err, results)
|
665 |
|
666 | MongoDB.prototype.near = (nearpt, count, callback) ->
|
667 | max = 40010000000
|
668 | nearquery = {
|
669 | geo: {
|
670 | $nearSphere: {
|
671 | $geometry: JSON.parse(nearpt.toGeoJson()).geometry,
|
672 | }
|
673 | }
|
674 | }
|
675 |
|
676 | this.query nearquery, (err, results) ->
|
677 | callback(err, (results || []).slice(0, count))
|
678 |
|
679 | MongoDB.prototype.inside = (withinpoly, callback) ->
|
680 | withinquery = {
|
681 | geo: {
|
682 | $geoWithin: {
|
683 | $geometry: JSON.parse(withinpoly.toGeoJson()).geometry
|
684 | }
|
685 | }
|
686 | }
|
687 | this.query withinquery, callback
|
688 |
|
689 |
|
690 |
|
691 | if exports
|
692 | exports.MapPLZ = MapPLZ
|
693 | exports.MapItem = MapItem
|
694 | exports.PostGIS = PostGIS
|
695 | exports.MongoDB = MongoDB
|