kopia lustrzana https://github.com/FacilMap/facilmap
136 wiersze
4.7 KiB
TypeScript
136 wiersze
4.7 KiB
TypeScript
import { CreationOptional, DataTypes, ForeignKey, InferAttributes, InferCreationAttributes, Model } from "sequelize";
|
|
import { BboxWithZoom, ID, Latitude, Longitude, Marker, MarkerCreate, MarkerUpdate, PadId } from "facilmap-types";
|
|
import { BboxWithExcept, createModel, dataDefinition, DataModel, getDefaultIdType, getPosType, getVirtualLatType, getVirtualLonType, makeNotNullForeignKey, validateColour } from "./helpers";
|
|
import Database from "./database";
|
|
import { getElevationForPoint } from "../elevation";
|
|
import { PadModel } from "./pad";
|
|
import { Point as GeoJsonPoint } from "geojson";
|
|
import { TypeModel } from "./type";
|
|
|
|
export interface MarkerModel extends Model<InferAttributes<MarkerModel>, InferCreationAttributes<MarkerModel>> {
|
|
id: CreationOptional<ID>;
|
|
padId: ForeignKey<PadModel["id"]>;
|
|
pos: GeoJsonPoint;
|
|
lat: Latitude;
|
|
lon: Longitude;
|
|
name: string | null;
|
|
typeId: ForeignKey<TypeModel["id"]>;
|
|
colour: string;
|
|
size: number;
|
|
symbol: string | null;
|
|
shape: string | null;
|
|
ele: number | null;
|
|
toJSON: () => Marker;
|
|
}
|
|
|
|
export default class DatabaseMarkers {
|
|
|
|
MarkerModel = createModel<MarkerModel>();
|
|
MarkerDataModel = createModel<DataModel>();
|
|
|
|
_db: Database;
|
|
|
|
constructor(database: Database) {
|
|
this._db = database;
|
|
|
|
this.MarkerModel.init({
|
|
id: getDefaultIdType(),
|
|
lat: getVirtualLatType(),
|
|
lon: getVirtualLonType(),
|
|
pos: getPosType(),
|
|
name : { type: DataTypes.TEXT, allowNull: true, get: function(this: MarkerModel) { return this.getDataValue("name") || "Untitled marker"; } },
|
|
colour : { type: DataTypes.STRING(6), allowNull: false, defaultValue: "ff0000", validate: validateColour },
|
|
size : { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, defaultValue: 25, validate: { min: 15 } },
|
|
symbol : { type: DataTypes.TEXT, allowNull: true },
|
|
shape : { type: DataTypes.TEXT, allowNull: true },
|
|
ele: {
|
|
type: DataTypes.INTEGER,
|
|
allowNull: true,
|
|
set: function(this: MarkerModel, v: number | null) {
|
|
// Round number to avoid integer column error in Postgres
|
|
this.setDataValue("ele", v != null ? Math.round(v) : v);
|
|
}
|
|
}
|
|
}, {
|
|
sequelize: this._db._conn,
|
|
// pos index is created in migration
|
|
modelName: "Marker"
|
|
});
|
|
|
|
this.MarkerDataModel.init(dataDefinition, {
|
|
sequelize: this._db._conn,
|
|
modelName: "MarkerData"
|
|
});
|
|
}
|
|
|
|
afterInit(): void {
|
|
const PadModel = this._db.pads.PadModel;
|
|
const TypeModel = this._db.types.TypeModel;
|
|
|
|
PadModel.hasMany(this.MarkerModel, makeNotNullForeignKey("Markers", "padId"));
|
|
this.MarkerModel.belongsTo(PadModel, makeNotNullForeignKey("pad", "padId"));
|
|
this.MarkerModel.belongsTo(TypeModel, makeNotNullForeignKey("type", "typeId", true));
|
|
|
|
this.MarkerDataModel.belongsTo(this.MarkerModel, makeNotNullForeignKey("marker", "markerId"));
|
|
this.MarkerModel.hasMany(this.MarkerDataModel, { foreignKey: "markerId" });
|
|
}
|
|
|
|
getPadMarkers(padId: PadId, bbox?: BboxWithZoom & BboxWithExcept): Highland.Stream<Marker> {
|
|
return this._db.helpers._getPadObjects<Marker>("Marker", padId, { where: this._db.helpers.makeBboxCondition(bbox) });
|
|
}
|
|
|
|
getPadMarkersByType(padId: PadId, typeId: ID): Highland.Stream<Marker> {
|
|
return this._db.helpers._getPadObjects<Marker>("Marker", padId, { where: { padId: padId, typeId: typeId } });
|
|
}
|
|
|
|
getMarker(padId: PadId, markerId: ID): Promise<Marker> {
|
|
return this._db.helpers._getPadObject("Marker", padId, markerId);
|
|
}
|
|
|
|
async createMarker(padId: PadId, data: MarkerCreate): Promise<Marker> {
|
|
const type = await this._db.types.getType(padId, data.typeId);
|
|
const elevation = await getElevationForPoint(data);
|
|
|
|
if(type.defaultColour)
|
|
data.colour = type.defaultColour;
|
|
if(type.defaultSize)
|
|
data.size = type.defaultSize;
|
|
if(type.defaultSymbol)
|
|
data.symbol = type.defaultSymbol;
|
|
if(type.defaultShape)
|
|
data.shape = type.defaultShape;
|
|
|
|
data.ele = elevation;
|
|
|
|
const result = await this._db.helpers._createPadObject<Marker>("Marker", padId, data);
|
|
|
|
await this._db.helpers._updateObjectStyles(result);
|
|
|
|
this._db.emit("marker", padId, result);
|
|
return result;
|
|
}
|
|
|
|
async updateMarker(padId: PadId, markerId: ID, data: MarkerUpdate, doNotUpdateStyles = false): Promise<Marker> {
|
|
const update = { ...data };
|
|
|
|
if (update.lat != null && update.lon != null)
|
|
update.ele = await getElevationForPoint({ lat: update.lat, lon: update.lon });
|
|
|
|
const result = await this._db.helpers._updatePadObject<Marker>("Marker", padId, markerId, update, doNotUpdateStyles);
|
|
|
|
if(!doNotUpdateStyles)
|
|
await this._db.helpers._updateObjectStyles(result);
|
|
|
|
this._db.emit("marker", padId, result);
|
|
|
|
return result;
|
|
}
|
|
|
|
async deleteMarker(padId: PadId, markerId: ID): Promise<Marker> {
|
|
const result = await this._db.helpers._deletePadObject<Marker>("Marker", padId, markerId);
|
|
this._db.emit("deleteMarker", padId, { id: result.id });
|
|
return result;
|
|
}
|
|
|
|
}
|