* add global getMapDataWithAttributeLikeGlobalQuery * add getMapDataWithAttributeLikeGlobalQuery for postgres * perform global search when position missing (sqlite) * perform global query when pos missing (postgres) * TrainelineOverlay: query full information on visible lines before drawing * hopefully fix errors, minor efficiency improvements * stupid mistake * you know it's probably late when mistakes like this happen * same for postgres * more optimizations
This commit is contained in:
parent
1ee54f9032
commit
25e177fbb9
@ -28,14 +28,23 @@ func (db *PostgresAccessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobject
|
|||||||
)
|
)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//attribute like search
|
if (q.Pos1 == nil || q.Pos2 == nil) {
|
||||||
rows, err = db.db.Query(getMapDataWithAttributeLikePosQuery,
|
//global attribute like search
|
||||||
q.Type,
|
rows, err = db.db.Query(getMapDataWithAttributeLikeGlobalQuery,
|
||||||
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
|
q.AttributeLike.Key, q.AttributeLike.Value,
|
||||||
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
|
q.Type,
|
||||||
q.AttributeLike.Key, q.AttributeLike.Value,
|
limit,
|
||||||
limit,
|
)
|
||||||
)
|
} else {
|
||||||
|
//attribute like search
|
||||||
|
rows, err = db.db.Query(getMapDataWithAttributeLikePosQuery,
|
||||||
|
q.Type,
|
||||||
|
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
|
||||||
|
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
|
||||||
|
q.AttributeLike.Key, q.AttributeLike.Value,
|
||||||
|
limit,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -29,6 +29,20 @@ and o.posx <= $5 and o.posy <= $6 and o.posz <= $7
|
|||||||
order by o.id
|
order by o.id
|
||||||
limit $10
|
limit $10
|
||||||
`
|
`
|
||||||
|
const getMapDataWithAttributeLikeGlobalQuery = `
|
||||||
|
select o.id, o.type, o.mtime,
|
||||||
|
o.x, o.y, o.z,
|
||||||
|
o.posx, o.posy, o.posz,
|
||||||
|
oa.key, oa.value
|
||||||
|
from objects o
|
||||||
|
left join object_attributes oa on o.id = oa.objectid
|
||||||
|
where o.id in (
|
||||||
|
select objectid from object_attributes where key = $2 and value ilike $3
|
||||||
|
)
|
||||||
|
and o.type = $1
|
||||||
|
order by o.id
|
||||||
|
limit $4
|
||||||
|
`
|
||||||
|
|
||||||
const removeMapDataQuery = `
|
const removeMapDataQuery = `
|
||||||
delete from objects where posx = $1 and posy = $2 and posz = $3
|
delete from objects where posx = $1 and posy = $2 and posz = $3
|
||||||
|
@ -28,14 +28,23 @@ func (db *Sqlite3Accessor) GetMapData(q *mapobjectdb.SearchQuery) ([]*mapobjectd
|
|||||||
)
|
)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//attribute like search
|
if (q.Pos1 == nil || q.Pos2 == nil) {
|
||||||
rows, err = db.db.Query(getMapDataWithAttributeLikePosQuery,
|
//global attribute like search
|
||||||
q.AttributeLike.Key, q.AttributeLike.Value,
|
rows, err = db.db.Query(getMapDataWithAttributeLikeGlobalQuery,
|
||||||
q.Type,
|
q.AttributeLike.Key, q.AttributeLike.Value,
|
||||||
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
|
q.Type,
|
||||||
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
|
limit,
|
||||||
limit,
|
)
|
||||||
)
|
} else {
|
||||||
|
//attribute like search
|
||||||
|
rows, err = db.db.Query(getMapDataWithAttributeLikePosQuery,
|
||||||
|
q.AttributeLike.Key, q.AttributeLike.Value,
|
||||||
|
q.Type,
|
||||||
|
q.Pos1.X, q.Pos1.Y, q.Pos1.Z,
|
||||||
|
q.Pos2.X, q.Pos2.Y, q.Pos2.Z,
|
||||||
|
limit,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -31,6 +31,21 @@ order by o.id
|
|||||||
limit ?
|
limit ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const getMapDataWithAttributeLikeGlobalQuery = `
|
||||||
|
select o.id, o.type, o.mtime,
|
||||||
|
o.x, o.y, o.z,
|
||||||
|
o.posx, o.posy, o.posz,
|
||||||
|
oa.key, oa.value
|
||||||
|
from objects o
|
||||||
|
left join object_attributes oa on o.id = oa.objectid
|
||||||
|
where o.id in (
|
||||||
|
select objectid from object_attributes where key = ? and value like ?
|
||||||
|
)
|
||||||
|
and o.type = ?
|
||||||
|
order by o.id
|
||||||
|
limit ?
|
||||||
|
`
|
||||||
|
|
||||||
const removeMapDataQuery = `
|
const removeMapDataQuery = `
|
||||||
delete from objects where posx = ? and posy = ? and posz = ?
|
delete from objects where posx = ? and posy = ? and posz = ?
|
||||||
`
|
`
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import AbstractGeoJsonOverlay from './AbstractGeoJsonOverlay.js';
|
import AbstractGeoJsonOverlay from './AbstractGeoJsonOverlay.js';
|
||||||
|
import { getMapObjects } from '../../api.js';
|
||||||
|
|
||||||
export default AbstractGeoJsonOverlay.extend({
|
export default AbstractGeoJsonOverlay.extend({
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
AbstractGeoJsonOverlay.prototype.initialize.call(this, "train");
|
AbstractGeoJsonOverlay.prototype.initialize.call(this, "train");
|
||||||
},
|
this.cache = {
|
||||||
|
lines: {}, // { "A1":[] }
|
||||||
createGeoJson: function(objects){
|
lineColors: {}, // { "A1": "red" }
|
||||||
|
lineFeat: []
|
||||||
var geoJsonLayer = L.geoJSON([], {
|
};
|
||||||
|
this.pendingQueries = [];
|
||||||
|
this.lastLayer = L.geoJSON([], {
|
||||||
onEachFeature: function(feature, layer){
|
onEachFeature: function(feature, layer){
|
||||||
if (feature.properties && feature.properties.popupContent) {
|
if (feature.properties && feature.properties.popupContent) {
|
||||||
layer.bindPopup(feature.properties.popupContent);
|
layer.bindPopup(feature.properties.popupContent);
|
||||||
@ -29,86 +32,101 @@ export default AbstractGeoJsonOverlay.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
createGeoJson: function(objects){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
var lines = {}; // { "A1":[] }
|
// which unique lines do objects belong to?
|
||||||
var lineColors = {}; // { "A1": "red" }
|
var lines = [];
|
||||||
|
|
||||||
//Sort and add lines
|
|
||||||
objects.forEach(function(obj){
|
objects.forEach(function(obj){
|
||||||
if (!obj.attributes.line)
|
if (obj.attributes.line && lines.indexOf(obj.attributes.line) == -1) {
|
||||||
return;
|
lines.push(obj.attributes.line);
|
||||||
|
|
||||||
var line = lines[obj.attributes.line];
|
|
||||||
if (!line){
|
|
||||||
line = [];
|
|
||||||
lines[obj.attributes.line] = line;
|
|
||||||
//default or new color
|
|
||||||
lineColors[obj.attributes.line] = "#ff7800";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.attributes.color){
|
|
||||||
//new color
|
|
||||||
lineColors[obj.attributes.line] = obj.attributes.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
line.push(obj);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Order by index and display
|
// query for each line, add to cache
|
||||||
Object.keys(lines).forEach(function(linename){
|
lines.forEach(function(linename){
|
||||||
lines[linename].sort(function(a,b){
|
if (!self.cache.lines[linename]){
|
||||||
return parseInt(a.attributes.index) - parseInt(b.attributes.index);
|
// only request if not in cache.
|
||||||
});
|
// if someone changed the train lines, the user has to reload. sorry.
|
||||||
|
self.pendingQueries.push(linename);
|
||||||
|
getMapObjects({
|
||||||
|
type: self.type,
|
||||||
|
attributelike: {
|
||||||
|
key: "line",
|
||||||
|
value: linename
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function(objects){
|
||||||
|
objects.sort(function(a,b){
|
||||||
|
return parseInt(a.attributes.index) - parseInt(b.attributes.index);
|
||||||
|
});
|
||||||
|
|
||||||
var coords = [];
|
self.cache.lines[linename] = objects;
|
||||||
var stations = [];
|
// already sorted, determine color
|
||||||
|
self.cache.lineColors[linename] = "#ff7800";
|
||||||
|
for (var i = objects.length-1; i >= 0; i--) {
|
||||||
|
// find the last element specifying a color
|
||||||
|
// as was previous behaviour, but be more efficient
|
||||||
|
if (objects[i].attributes.color){
|
||||||
|
self.cache.lineColors[linename] = objects[i].attributes.color;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Add stations
|
var feat = {
|
||||||
lines[linename].forEach(function(entry){
|
coords: [],
|
||||||
coords.push([entry.x, entry.z]);
|
stations: [],
|
||||||
|
feature: null
|
||||||
|
};
|
||||||
|
//Add stations
|
||||||
|
objects.forEach(function(entry){
|
||||||
|
feat.coords.push([entry.x, entry.z]);
|
||||||
|
|
||||||
if (entry.attributes.station) {
|
if (entry.attributes.station) {
|
||||||
stations.push({
|
feat.stations.push({
|
||||||
"type": "Feature",
|
"type": "Feature",
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": entry.attributes.station,
|
"name": entry.attributes.station,
|
||||||
"color": lineColors[linename],
|
"color": self.cache.lineColors[linename],
|
||||||
"popupContent": "<b>Train-station (Line " + entry.attributes.line + ")</b><hr>" +
|
"popupContent": "<b>Train-station (Line " + entry.attributes.line + ")</b><hr>" +
|
||||||
entry.attributes.station
|
entry.attributes.station
|
||||||
},
|
},
|
||||||
"geometry": {
|
"geometry": {
|
||||||
"type": "Point",
|
"type": "Point",
|
||||||
"coordinates": [entry.x, entry.z]
|
"coordinates": [entry.x, entry.z]
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var feature = {
|
feat.feature = {
|
||||||
"type":"Feature",
|
"type":"Feature",
|
||||||
"geometry": {
|
"geometry": {
|
||||||
"type":"LineString",
|
"type":"LineString",
|
||||||
"coordinates":coords
|
"coordinates": feat.coords
|
||||||
},
|
},
|
||||||
"properties":{
|
"properties":{
|
||||||
"name": linename,
|
"name": linename,
|
||||||
"color": lineColors[linename],
|
"color": self.cache.lineColors[linename],
|
||||||
"popupContent": "<b>Train-line (" + linename + ")</b>"
|
"popupContent": "<b>Train-line (" + linename + ")</b>"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//line-points
|
self.cache.lineFeat[linename] = feat;
|
||||||
geoJsonLayer.addData(feature);
|
|
||||||
|
|
||||||
//stations
|
|
||||||
stations.forEach(function(stationfeature){
|
|
||||||
geoJsonLayer.addData(stationfeature);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
//line-points
|
||||||
|
self.lastLayer.addData(feat.feature);
|
||||||
|
|
||||||
|
//stations
|
||||||
|
feat.stations.forEach(function(stationfeature){
|
||||||
|
self.lastLayer.addData(stationfeature);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return geoJsonLayer;
|
return self.lastLayer;
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user