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() {