Bug fixes and backup functionality
This commit is contained in:
parent
12861ced7f
commit
488260c733
5 changed files with 119 additions and 10 deletions
|
@ -12,5 +12,16 @@ create table borders (
|
|||
cmnt varchar(500)
|
||||
);
|
||||
|
||||
create table borders_backup (
|
||||
backup varchar(30) not null,
|
||||
name varchar(200) not null,
|
||||
geom geometry not null,
|
||||
disabled boolean not null default FALSE,
|
||||
count_k integer,
|
||||
modified timestamp not null,
|
||||
cmnt varchar(500),
|
||||
primary key (backup, name)
|
||||
);
|
||||
|
||||
create index border_idx on borders using gist (geom);
|
||||
create index tiles_idx on tiles using gist (tile);
|
||||
|
|
|
@ -65,7 +65,7 @@ fi
|
|||
|
||||
# 3. Make osm_borders table
|
||||
echo Creating osm_borders table
|
||||
psql $DATABASE -c "drop table if exists osm_borders; create table osm_borders as select min(osm_id) as osm_id, ST_Transform(ST_Collect(way),4326) as way, admin_level::int as admin_level, coalesce(max(\"name:en\"), name) as name from planet_osm_polygon where boundary='administrative' and admin_level in ('2', '3', '4', '5', '6') group by name, admin_level;" || exit 3
|
||||
psql $DATABASE -c "drop table if exists osm_borders; create table osm_borders as select min(osm_id) as osm_id, ST_Buffer(ST_Transform(ST_Collect(way),4326), 0) as way, admin_level::int as admin_level, coalesce(max(\"name:en\"), name) as name from planet_osm_polygon where boundary='administrative' and admin_level in ('2', '3', '4', '5', '6') group by name, admin_level;" || exit 3
|
||||
|
||||
# 4. Copy it to the borders database
|
||||
echo Copying osm_borders table to the borders database
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
from flask import Flask, g, request, json, jsonify, abort, Response
|
||||
from flask.ext.cors import CORS
|
||||
from flask.ext.compress import Compress
|
||||
import psycopg2
|
||||
from lxml import etree
|
||||
from xml.sax.saxutils import quoteattr
|
||||
import psycopg2
|
||||
|
||||
TABLE = 'borders'
|
||||
OSM_TABLE = 'osm_borders'
|
||||
BACKUP = 'borders_backup'
|
||||
READONLY = False
|
||||
|
||||
app = Flask(__name__)
|
||||
|
@ -230,7 +231,13 @@ def divide():
|
|||
if prefix != '':
|
||||
prefix = '{}_'.format(prefix);
|
||||
cur = g.conn.cursor()
|
||||
cur.execute('insert into {table} (geom, name, modified, count_k) select o.way as way, %s || name, now(), -1 from {osm}, (select way from {osm} where name like %s) r where ST_Contains(r.way, o.way) and {query};'.format(table=TABLE, osm=OSM_TABLE, query=query), (prefix, like,))
|
||||
cur.execute('''insert into {table} (geom, name, modified, count_k)
|
||||
select o.way as way, %s || name, now(), -1
|
||||
from {osm} o, (
|
||||
select way from {osm} where name like %s
|
||||
) r
|
||||
where ST_Contains(r.way, o.way) and {query};
|
||||
'''.format(table=TABLE, osm=OSM_TABLE, query=query), (prefix, like,))
|
||||
cur.execute('delete from {} where name = %s;'.format(TABLE), (name,))
|
||||
g.conn.commit()
|
||||
return jsonify(status='ok')
|
||||
|
@ -273,6 +280,39 @@ def draw_hull():
|
|||
g.conn.commit()
|
||||
return jsonify(status='ok')
|
||||
|
||||
@app.route('/backup')
|
||||
def backup_do():
|
||||
cur = g.conn.cursor()
|
||||
cur.execute("SELECT to_char(now(), 'IYYY-MM-DD HH24:MI'), max(backup) from {};".format(BACKUP))
|
||||
(timestamp, tsmax) = cur.fetchone()
|
||||
if timestamp == tsmax:
|
||||
return jsonify(status='please try again later')
|
||||
cur.execute('INSERT INTO {backup} (backup, name, geom, disabled, count_k, modified, cmnt) SELECT %s, name, geom, disabled, count_k, modified, cmnt from {table};'.format(backup=BACKUP, table=TABLE), (timestamp,))
|
||||
g.conn.commit()
|
||||
return jsonify(status='ok')
|
||||
|
||||
@app.route('/restore')
|
||||
def backup_restore():
|
||||
ts = request.args.get('timestamp')
|
||||
cur = g.conn.cursor()
|
||||
cur.execute('SELECT count(1) from {} where backup = %s;'.format(BACKUP), (ts,))
|
||||
(count,) = cur.fetchone()
|
||||
if count <= 0:
|
||||
return jsonify(status='no such timestamp')
|
||||
cur.execute('DELETE FROM {};'.format(TABLE))
|
||||
cur.execute('INSERT INTO {table} (name, geom, disabled, count_k, modified, cmnt) SELECT name, geom, disabled, count_k, modified, cmnt from {backup} where backup = %s;'.format(backup=BACKUP, table=TABLE), (ts,))
|
||||
g.conn.commit()
|
||||
return jsonify(status='ok')
|
||||
|
||||
@app.route('/backlist')
|
||||
def backup_list():
|
||||
cur = g.conn.cursor()
|
||||
cur.execute("SELECT backup, count(1) from {} group by backup order by backup desc;".format(BACKUP))
|
||||
result = []
|
||||
for res in cur:
|
||||
result.append({ 'timestamp': res[0], 'text': res[0], 'count': res[1] })
|
||||
return jsonify(backups=result)
|
||||
|
||||
@app.route('/josm')
|
||||
def make_osm():
|
||||
xmin = request.args.get('xmin')
|
||||
|
@ -496,7 +536,6 @@ def import_osm():
|
|||
j = i + 1
|
||||
while way[0] != way[-1] and j < len(multi):
|
||||
print 'maybe way with start={}, end={}?'.format(multi[j]['nodes'][0], multi[j]['nodes'][-1])
|
||||
# todo: do not modify source way!!!
|
||||
new_way = append_way(way, multi[j]['nodes'])
|
||||
if new_way:
|
||||
multi[i] = dict(multi[i])
|
||||
|
@ -553,7 +592,7 @@ def import_osm():
|
|||
updated = updated + 1
|
||||
else:
|
||||
# create
|
||||
cur.execute('insert into {table} (name, disabled, geom, modified, count_k) values (%s, %s, %s, now(), -1);'.format(table=TABLE), (name, region['disabled'], region['wkt']))
|
||||
cur.execute('insert into {table} (name, disabled, geom, modified, count_k) values (%s, %s, ST_GeomFromText(%s, 4326), now(), -1);'.format(table=TABLE), (name, region['disabled'], region['wkt']))
|
||||
added = added + 1
|
||||
g.conn.commit()
|
||||
return jsonify(regions=len(regions), added=added, updated=updated)
|
||||
|
|
|
@ -18,9 +18,9 @@ function init() {
|
|||
map.addLayer(bordersLayer);
|
||||
|
||||
map.on('moveend', function() {
|
||||
if( map.getZoom() >= 4 )
|
||||
if( map.getZoom() >= 5 )
|
||||
updateBorders();
|
||||
$('#b_josm').css('visibility', map.getZoom() >= 8 ? 'visible' : 'hidden');
|
||||
$('#b_josm').css('visibility', map.getZoom() >= 7 ? 'visible' : 'hidden');
|
||||
});
|
||||
|
||||
document.getElementById('filefm').action = server + '/import';
|
||||
|
@ -147,7 +147,7 @@ function selectLayer(e) {
|
|||
if( props['disabled'] )
|
||||
e.target.setStyle({ fillOpacity: 0.01 });
|
||||
$('#b_name').text(props['name']);
|
||||
$('#b_size').text(Math.round(props['count_k'] * 8 / 1000000) + ' MB');
|
||||
$('#b_size').text(Math.round(props['count_k'] * 8 / 1024 / 1024) + ' MB');
|
||||
//$('#b_nodes').text(borders[selectedId].layer.getLatLngs()[0].length);
|
||||
$('#b_nodes').text(props['nodes']);
|
||||
$('#b_date').text(props['modified']);
|
||||
|
@ -503,7 +503,7 @@ function bDivideDrawPreview(geojson) {
|
|||
return;
|
||||
divPreview = L.geoJson(geojson, {
|
||||
style: function(f) {
|
||||
return { color: 'blue', weight: 1 };
|
||||
return { color: 'blue', weight: 1, fill: false };
|
||||
}
|
||||
});
|
||||
map.addLayer(divPreview);
|
||||
|
@ -551,3 +551,52 @@ function bHull() {
|
|||
success: updateBorders
|
||||
});
|
||||
}
|
||||
|
||||
function bBackup() {
|
||||
$('#actions').css('display', 'none');
|
||||
$('#backup_saving').css('display', 'none');
|
||||
$('#backup_restoring').css('display', 'none');
|
||||
$('#backup_save').attr('disabled', false);
|
||||
$('#backup_list').text('');
|
||||
$('#backup').css('display', 'block');
|
||||
$.ajax(server + '/backlist', {
|
||||
success: updateBackupList
|
||||
});
|
||||
}
|
||||
|
||||
function bBackupCancel() {
|
||||
$('#actions').css('display', 'block');
|
||||
$('#backup').css('display', 'none');
|
||||
}
|
||||
|
||||
function updateBackupList(data) {
|
||||
var list = $('#backup_list');
|
||||
list.text('');
|
||||
if( !data || !('backups' in data) )
|
||||
return;
|
||||
for( var i = 0; i < data.backups.length; i++ ) {
|
||||
var b = data.backups[i];
|
||||
var a = document.createElement('a');
|
||||
a.href = '#';
|
||||
a.onclick = (function(id, name) { return function() { bBackupRestore(id); return false } })(b['timestamp']);
|
||||
list.append(a, $('<br>'));
|
||||
$(a).text(b['text'] + ' (' + b['count'] + ')');
|
||||
}
|
||||
}
|
||||
|
||||
function bBackupSave() {
|
||||
$.ajax(server + '/backup', {
|
||||
success: bBackupCancel
|
||||
});
|
||||
$('#backup_save').attr('disabled', true);
|
||||
$('#backup_saving').css('display', 'block');
|
||||
}
|
||||
|
||||
function bBackupRestore(timestamp) {
|
||||
$.ajax(server + '/restore', {
|
||||
data: { 'timestamp': timestamp },
|
||||
success: function() { bBackupCancel(); updateBorders(); }
|
||||
});
|
||||
$('#backup_list').text('');
|
||||
$('#backup_restoring').css('display', 'block');
|
||||
}
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
#osm_actions { display: none; margin-top: 1em; }
|
||||
#info { margin-top: 2em; }
|
||||
#b_delete, #b_clear { font-size: 8pt; }
|
||||
#rename, #split, #join, #point, #divide { display: none; }
|
||||
#rename, #split, #join, #point, #divide, #backup { display: none; }
|
||||
.actions input[type='text'] { width: 150px; }
|
||||
#header { border-bottom: 1px solid gray; margin-bottom: 1em; padding-bottom: 1em; }
|
||||
#f_topo, #f_chars, #f_comments { font-size: 10pt; }
|
||||
#backup_saving, #backup_restoring { margin-bottom: 1em; }
|
||||
</style>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
|
@ -58,6 +59,7 @@
|
|||
Импорт <input type="file" accept=".osm,.xml" name="file" id="b_import" onchange="bImport();" style="max-width: 100px;">
|
||||
</form>
|
||||
<iframe name="import_frame" style="display: none;" width="230" height="80" src="about:blank"></iframe>
|
||||
<button onclick="bBackup()">Архив границ</button>
|
||||
</div>
|
||||
<div id="actions" class="actions">
|
||||
<button onclick="bDisable()" id="b_disable">Убрать</button>
|
||||
|
@ -131,6 +133,14 @@
|
|||
<br>
|
||||
<button onclick="bDivideCancel()">Вернуться</button>
|
||||
</div>
|
||||
<div id="backup" class="actions">
|
||||
<button onclick="bBackupSave()" id="backup_save">Сохранить границы</button>
|
||||
<div id="backup_saving">Копирую границы...</div>
|
||||
<div id="backup_restoring">Восстанавливаю границы...</div>
|
||||
<div>Или выберите набор границ для восстановления:</div>
|
||||
<div id="backup_list"></div>
|
||||
<button onclick="bBackupCancel()">Вернуться</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="map"></div>
|
||||
</body>
|
||||
|
|
Loading…
Add table
Reference in a new issue