From edc0ae03a02cf0f19414d4fe933d5f962eb03dda Mon Sep 17 00:00:00 2001 From: Ilya Zverev Date: Fri, 20 Mar 2015 17:25:27 +0300 Subject: [PATCH] remade markers, fixed some bugs --- server/borders-api.py | 50 ++++++++++++++++++++++++++++++------- www/borders.js | 57 +++++++++++++++++++++++-------------------- 2 files changed, 72 insertions(+), 35 deletions(-) diff --git a/server/borders-api.py b/server/borders-api.py index a280e62..b8cbe08 100755 --- a/server/borders-api.py +++ b/server/borders-api.py @@ -11,7 +11,7 @@ OSM_TABLE = 'osm_borders' READONLY = False app = Flask(__name__) -app.debug=True +#app.debug=True Compress(app) CORS(app) @@ -51,6 +51,25 @@ def query_bbox(): result.append(feature) return jsonify(type='FeatureCollection', features=result) +@app.route('/small') +def query_small_in_bbox(): + xmin = request.args.get('xmin') + xmax = request.args.get('xmax') + ymin = request.args.get('ymin') + ymax = request.args.get('ymax') + cur = g.conn.cursor() + cur.execute('''SELECT name, round(ST_Area(geography(ring))) as area, ST_X(ST_Centroid(ring)), ST_Y(ST_Centroid(ring)) + FROM ( + SELECT name, (ST_Dump(geom)).geom as ring + FROM {table} + WHERE geom && ST_MakeBox2D(ST_Point(%s, %s), ST_Point(%s, %s)) + ) g + WHERE ST_Area(geography(ring)) < 1000000;'''.format(table=TABLE), (xmin, ymin, xmax, ymax)) + result = [] + for rec in cur: + result.append({ 'name': rec[0], 'area': rec[1], 'lon': float(rec[2]), 'lat': float(rec[3]) }) + return jsonify(features=result) + @app.route('/hasosm') def check_osm_table(): res = False @@ -261,7 +280,7 @@ def make_osm(): ymin = request.args.get('ymin') ymax = request.args.get('ymax') cur = g.conn.cursor() - cur.execute('SELECT name, disabled, ST_AsGeoJSON(geom, 7) as geometry FROM {table} WHERE geom && ST_MakeBox2D(ST_Point(%s, %s), ST_Point(%s, %s));'.format(table=TABLE), (xmin, ymin, xmax, ymax)) + cur.execute('SELECT name, disabled, ST_AsGeoJSON(geom, 7) as geometry FROM {table} WHERE ST_Intersects(ST_SetSRID(ST_Buffer(ST_MakeBox2D(ST_Point(%s, %s), ST_Point(%s, %s)), 0.3), 4326), geom);'.format(table=TABLE), (xmin, ymin, xmax, ymax)) node_pool = { 'id': 1 } # 'lat_lon': id regions = [] # { name: name, rings: [['outer', [ids]], ['inner', [ids]], ...] } @@ -283,9 +302,12 @@ def make_osm(): xml = xml + ''.format(id=node_id, lat=lat, lon=lon) wrid = 1 + ways = {} # json: id for region in regions: - if len(region['rings']) == 1: + w1key = ring_hash(region['rings'][0][1]) + if len(region['rings']) == 1 and w1key not in ways: # simple case: a way + ways[w1key] = wrid xml = xml + ''.format(id=wrid) xml = xml + ''.format(quoteattr(region['name'])) if region['disabled']: @@ -303,16 +325,26 @@ def make_osm(): if region['disabled']: rxml = rxml + '' for ring in region['rings']: - xml = xml + ''.format(id=wrid) - rxml = rxml + ''.format(ref=wrid, role=ring[0]) - for nd in ring[1]: - xml = xml + ''.format(ref=nd) - xml = xml + '' - wrid = wrid + 1 + wkey = ring_hash(ring[1]) + if wkey in ways: + # already have that way + rxml = rxml + ''.format(ref=ways[wkey], role=ring[0]) + else: + ways[wkey] = wrid + xml = xml + ''.format(id=wrid) + rxml = rxml + ''.format(ref=wrid, role=ring[0]) + for nd in ring[1]: + xml = xml + ''.format(ref=nd) + xml = xml + '' + wrid = wrid + 1 xml = xml + rxml + '' xml = xml + '' return Response(xml, mimetype='application/x-osm+xml') +def ring_hash(refs): + #return json.dumps(refs) + return hash(tuple(sorted(refs))) + def parse_polygon(node_pool, rings, polygon): role = 'outer' for ring in polygon: diff --git a/www/borders.js b/www/borders.js index 069ac21..2ddf264 100644 --- a/www/borders.js +++ b/www/borders.js @@ -61,9 +61,6 @@ function processResult(data) { } } - if( tooSmallLayer != null ) - tooSmallLayer.clearLayers(); - for( var f = 0; f < data.features.length; f++ ) { var layer = L.GeoJSON.geometryToLayer(data.features[f].geometry), props = data.features[f].properties; @@ -76,6 +73,37 @@ function processResult(data) { } else { selectLayer(null); } + + if( tooSmallLayer != null ) { + tooSmallLayer.clearLayers(); + var b = map.getBounds(); + $.ajax(server + '/small', { + data: { + 'xmin': b.getWest(), + 'xmax': b.getEast(), + 'ymin': b.getSouth(), + 'ymax': b.getNorth() + }, + success: processTooSmall, + dataType: 'json' + }); + } +} + +function processTooSmall(data) { + if( tooSmallLayer == null || !data || !('features' in data) ) + return; + tooSmallLayer.clearLayers(); + var i, pt, tsm; + for( i = 0; i < data.features.length; i++ ) { + pt = data.features[i]; + if( pt.name in borders ) { + tsm = L.marker([pt.lat, pt.lon], { title: pt.name + '\n' + 'Площадь: ' + L.Util.formatNum(pt.area / 1000000, 2) + ' км²' }); + tsm.pLayer = borders[pt.name].layer; + tsm.on('click', selectLayer); + tooSmallLayer.addLayer(tsm); + } + } } function updateBorder(id, layer, props) { @@ -88,12 +116,6 @@ function updateBorder(id, layer, props) { borders[id].layer = layer; layer.id = id; bordersLayer.addLayer(layer); - if( tooSmallLayer != null && props['area'] < KM2_AREA_TOO_SMALL * 1000000 ) { - var tsm = L.marker(layer.getBounds().getCenter()); - tsm.pLayer = layer; - tsm.on('click', selectLayer); - tooSmallLayer.addLayer(tsm); - } layer.setStyle(STYLE_BORDER); if( borders[id]['disabled'] ) layer.setStyle({ fillOpacity: 0.01 }); @@ -243,23 +265,6 @@ function bJosmZoom() { function bImport() { document.getElementById('filefm').submit(); - // todo: state that file is uploading somewhere -/* var file = document.getElementById('b_import').files[0]; - var fr = new FileReader(); - fr.onload = function() { bImportSend(fr.result); }; - fr.readAsText(file);*/ -} - -function bImportSend(data) { - // todo: state that file has been sent - $.ajax(server + '/import', { - data: { - 'file': data - }, - type: 'POST', - datatype: 'json', - success: updateBorders - }); } function bShowRename() {