@ngageoint/mage.service 6.2.8 → 6.2.10-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/@types/express/index.d.ts +1 -1
- package/lib/adapters/icons/adapters.icons.db.mongoose.js.map +1 -1
- package/lib/adapters/observations/adapters.observations.controllers.web.d.ts.map +1 -1
- package/lib/adapters/observations/adapters.observations.controllers.web.js +7 -11
- package/lib/adapters/observations/adapters.observations.controllers.web.js.map +1 -1
- package/lib/adapters/observations/adapters.observations.dto.ecma404-json.d.ts +13 -0
- package/lib/adapters/observations/adapters.observations.dto.ecma404-json.d.ts.map +1 -0
- package/lib/adapters/observations/adapters.observations.dto.ecma404-json.js +62 -0
- package/lib/adapters/observations/adapters.observations.dto.ecma404-json.js.map +1 -0
- package/lib/api/attachment.d.ts +3 -0
- package/lib/api/attachment.d.ts.map +1 -1
- package/lib/api/attachment.js +3 -0
- package/lib/api/attachment.js.map +1 -1
- package/lib/api/icon.d.ts +51 -20
- package/lib/api/icon.js +1 -1
- package/lib/api/icon.js.map +1 -1
- package/lib/api/location.d.ts +1 -3
- package/lib/api/location.d.ts.map +1 -1
- package/lib/api/user.d.ts.map +1 -1
- package/lib/api/user.js +1 -2
- package/lib/api/user.js.map +1 -1
- package/lib/app.api/observations/app.api.observations.d.ts +6 -1
- package/lib/app.api/observations/app.api.observations.d.ts.map +1 -1
- package/lib/app.api/observations/app.api.observations.js +1 -1
- package/lib/app.api/observations/app.api.observations.js.map +1 -1
- package/lib/app.d.ts +2 -2
- package/lib/app.d.ts.map +1 -1
- package/lib/app.impl/observations/app.impl.observations.d.ts.map +1 -1
- package/lib/app.impl/observations/app.impl.observations.js +15 -2
- package/lib/app.impl/observations/app.impl.observations.js.map +1 -1
- package/lib/app.js +5 -3
- package/lib/app.js.map +1 -1
- package/lib/authentication/saml.d.ts.map +1 -1
- package/lib/authentication/saml.js +15 -14
- package/lib/authentication/saml.js.map +1 -1
- package/lib/dist-package.json +48 -46
- package/lib/docs/auth/local.yaml +1 -2
- package/lib/entities/authorization/entities.permissions.d.ts +7 -1
- package/lib/entities/authorization/entities.permissions.d.ts.map +1 -1
- package/lib/entities/authorization/entities.permissions.js +7 -2
- package/lib/entities/authorization/entities.permissions.js.map +1 -1
- package/lib/entities/entities.global.d.ts +6 -0
- package/lib/entities/entities.global.d.ts.map +1 -1
- package/lib/entities/entities.global.js +12 -1
- package/lib/entities/entities.global.js.map +1 -1
- package/lib/entities/events/entities.events.d.ts.map +1 -1
- package/lib/entities/events/entities.events.forms.d.ts +9 -1
- package/lib/entities/events/entities.events.forms.d.ts.map +1 -1
- package/lib/entities/events/entities.events.forms.js +24 -3
- package/lib/entities/events/entities.events.forms.js.map +1 -1
- package/lib/entities/events/entities.events.js.map +1 -1
- package/lib/entities/locations/entities.locations.d.ts +30 -0
- package/lib/entities/locations/entities.locations.d.ts.map +1 -0
- package/lib/entities/locations/entities.locations.js +3 -0
- package/lib/entities/locations/entities.locations.js.map +1 -0
- package/lib/entities/observations/entities.observations.d.ts +24 -4
- package/lib/entities/observations/entities.observations.d.ts.map +1 -1
- package/lib/entities/observations/entities.observations.js +20 -16
- package/lib/entities/observations/entities.observations.js.map +1 -1
- package/lib/environment/env.js +1 -1
- package/lib/environment/env.js.map +1 -1
- package/lib/export/csv.d.ts +19 -9
- package/lib/export/csv.d.ts.map +1 -1
- package/lib/export/csv.js +255 -228
- package/lib/export/csv.js.map +1 -1
- package/lib/export/exporter.d.ts +37 -10
- package/lib/export/exporter.d.ts.map +1 -1
- package/lib/export/exporter.js +67 -35
- package/lib/export/exporter.js.map +1 -1
- package/lib/export/geojson.d.ts +9 -8
- package/lib/export/geojson.d.ts.map +1 -1
- package/lib/export/geojson.js +162 -143
- package/lib/export/geojson.js.map +1 -1
- package/lib/export/geopackage.d.ts +29 -23
- package/lib/export/geopackage.d.ts.map +1 -1
- package/lib/export/geopackage.js +657 -589
- package/lib/export/geopackage.js.map +1 -1
- package/lib/export/index.d.ts +17 -0
- package/lib/export/index.d.ts.map +1 -0
- package/lib/export/index.js +28 -0
- package/lib/export/index.js.map +1 -0
- package/lib/export/kml.d.ts +11 -8
- package/lib/export/kml.d.ts.map +1 -1
- package/lib/export/kml.js +152 -106
- package/lib/export/kml.js.map +1 -1
- package/lib/export/kmlWriter.d.ts +23 -22
- package/lib/export/kmlWriter.d.ts.map +1 -1
- package/lib/export/kmlWriter.js +258 -181
- package/lib/export/kmlWriter.js.map +1 -1
- package/lib/express.js +2 -4
- package/lib/express.js.map +1 -1
- package/lib/migrations/030-saml-settings.d.ts +4 -0
- package/lib/migrations/030-saml-settings.d.ts.map +1 -0
- package/lib/migrations/030-saml-settings.js +96 -0
- package/lib/migrations/030-saml-settings.js.map +1 -0
- package/lib/models/authentication.js +1 -1
- package/lib/models/authenticationconfiguration.js +0 -1
- package/lib/models/authenticationconfiguration.js.map +1 -1
- package/lib/models/event.d.ts +4 -2
- package/lib/models/event.js +1 -1
- package/lib/models/event.js.map +1 -1
- package/lib/models/export.d.ts +56 -17
- package/lib/models/export.d.ts.map +1 -1
- package/lib/models/export.js.map +1 -1
- package/lib/models/icon.d.ts +24 -9
- package/lib/models/icon.d.ts.map +1 -1
- package/lib/models/icon.js +3 -6
- package/lib/models/icon.js.map +1 -1
- package/lib/models/location.d.ts +40 -8
- package/lib/models/location.d.ts.map +1 -1
- package/lib/models/location.js +2 -0
- package/lib/models/location.js.map +1 -1
- package/lib/models/observation.d.ts +30 -3
- package/lib/models/observation.js.map +1 -1
- package/lib/models/user.d.ts +3 -0
- package/lib/models/user.js +1 -1
- package/lib/provision/index.js +1 -1
- package/lib/provision/index.js.map +1 -1
- package/lib/routes/authenticationconfigurations.d.ts.map +1 -1
- package/lib/routes/authenticationconfigurations.js +4 -5
- package/lib/routes/authenticationconfigurations.js.map +1 -1
- package/lib/routes/events.d.ts.map +1 -1
- package/lib/routes/events.js +19 -10
- package/lib/routes/events.js.map +1 -1
- package/lib/routes/exports.d.ts +3 -2
- package/lib/routes/exports.d.ts.map +1 -1
- package/lib/routes/exports.js +121 -79
- package/lib/routes/exports.js.map +1 -1
- package/lib/routes/imports.d.ts.map +1 -1
- package/lib/routes/imports.js +4 -2
- package/lib/routes/imports.js.map +1 -1
- package/lib/routes/layers.d.ts.map +1 -1
- package/lib/routes/layers.js +11 -45
- package/lib/routes/layers.js.map +1 -1
- package/lib/routes/locations.d.ts.map +1 -1
- package/lib/routes/locations.js +7 -3
- package/lib/routes/locations.js.map +1 -1
- package/lib/routes/routes.types.d.ts +9 -0
- package/lib/routes/setup.js +1 -1
- package/lib/routes/setup.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/npm-shrinkwrap.json +22340 -0
- package/package.json +48 -46
- package/lib/export/exporterFactory.d.ts +0 -11
- package/lib/export/exporterFactory.d.ts.map +0 -1
- package/lib/export/exporterFactory.js +0 -17
- package/lib/export/exporterFactory.js.map +0 -1
package/lib/export/geopackage.js
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,528 +31,699 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
31
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
32
|
});
|
|
10
33
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const util = require('util'), fs = require('fs'), api = require('../api'), archiver = require('archiver'), moment = require('moment'), log = require('winston'), path = require('path'), Exporter = require('./exporter'), GeoPackageAPI = require('@ngageoint/geopackage'), environment = require('../environment/env'), os = require('os'), wkx = require('wkx'), User = require('../models/user');
|
|
14
|
-
const attachmentBase = environment.attachmentBaseDirectory;
|
|
15
|
-
const pathToGeoPackageModule = path.resolve(path.dirname(require.resolve('@ngageoint/geopackage/package.json')));
|
|
16
|
-
GeoPackageAPI.setCanvasKitWasmLocateFile(file => `${pathToGeoPackageModule}/dist/canvaskit/${file}`);
|
|
17
|
-
function GeoPackage(options) {
|
|
18
|
-
GeoPackage.super_.call(this, options);
|
|
19
|
-
this.iconMap = {};
|
|
20
|
-
}
|
|
21
|
-
util.inherits(GeoPackage, Exporter);
|
|
22
|
-
module.exports = GeoPackage;
|
|
23
|
-
GeoPackage.prototype.export = function (streamable) {
|
|
24
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
log.info('Export the GeoPackage');
|
|
26
|
-
const downloadedFileName = 'mage-' + this._event.name;
|
|
27
|
-
const archive = archiver('zip');
|
|
28
|
-
archive.pipe(streamable);
|
|
29
|
-
try {
|
|
30
|
-
const filePath = yield this.createGeoPackageFile();
|
|
31
|
-
const gp = yield GeoPackageAPI.GeoPackageAPI.create(filePath);
|
|
32
|
-
yield this.createUserTable(gp);
|
|
33
|
-
yield this.createUserFeatureTableStyles(gp);
|
|
34
|
-
if (this._filter.exportObservations) {
|
|
35
|
-
yield this.addFormDataToGeoPackage(gp);
|
|
36
|
-
yield this.createFormAttributeTables(gp);
|
|
37
|
-
yield this.createObservationTable(gp);
|
|
38
|
-
yield this.createObservationFeatureTableStyles(gp);
|
|
39
|
-
yield this.addObservationsToGeoPackage(gp);
|
|
40
|
-
}
|
|
41
|
-
if (this._filter.exportLocations) {
|
|
42
|
-
yield this.addLocationsToGeoPackage(gp);
|
|
43
|
-
}
|
|
44
|
-
log.info(`export geopackage created: ${filePath}`);
|
|
45
|
-
archive.append(fs.createReadStream(filePath), { name: downloadedFileName + '.gpkg' });
|
|
46
|
-
archive.on('end', function () {
|
|
47
|
-
log.info(`removing temporary export geopackage file ${filePath}`);
|
|
48
|
-
fs.unlink(filePath, function () {
|
|
49
|
-
gp.close();
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
archive.finalize();
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
log.error(`error exporting geopackage`, err);
|
|
56
|
-
throw err;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
59
36
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.GeoPackage = void 0;
|
|
39
|
+
const relationType_1 = require("@ngageoint/geopackage/dist/lib/extension/relatedTables/relationType");
|
|
40
|
+
const envelopeBuilder_1 = require("@ngageoint/geopackage/dist/lib/geom/envelopeBuilder");
|
|
41
|
+
const GPKG = __importStar(require("@ngageoint/geopackage"));
|
|
42
|
+
const geopackage_1 = require("@ngageoint/geopackage");
|
|
43
|
+
const util_1 = __importDefault(require("util"));
|
|
44
|
+
const fs_1 = __importDefault(require("fs"));
|
|
45
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
46
|
+
const archiver_1 = __importDefault(require("archiver"));
|
|
47
|
+
const moment_1 = __importDefault(require("moment"));
|
|
48
|
+
const os_1 = __importDefault(require("os"));
|
|
49
|
+
const path_1 = __importDefault(require("path"));
|
|
50
|
+
const wkx_1 = __importDefault(require("wkx"));
|
|
51
|
+
const exporter_1 = require("./exporter");
|
|
52
|
+
const api_1 = __importDefault(require("../api"));
|
|
53
|
+
const env_1 = __importDefault(require("../environment/env"));
|
|
54
|
+
const user_1 = __importDefault(require("../models/user"));
|
|
55
|
+
// TODO: we really need to revamp our logging
|
|
56
|
+
const logger = require('../logger');
|
|
57
|
+
const log = ['debug', 'info', 'warn', 'error', 'log'].reduce((log, methodName) => {
|
|
58
|
+
const logMethod = logger[methodName];
|
|
59
|
+
return Object.assign(Object.assign({}, log), { [methodName]: (...args) => logMethod('[export:geopackage]', ...args) });
|
|
60
|
+
}, {});
|
|
61
|
+
const attachmentBase = env_1.default.attachmentBaseDirectory;
|
|
62
|
+
class GeoPackage extends exporter_1.Exporter {
|
|
63
|
+
constructor() {
|
|
64
|
+
super(...arguments);
|
|
65
|
+
this.iconCache = new IconTreeCache();
|
|
66
|
+
this.observationStyles = null;
|
|
67
|
+
}
|
|
68
|
+
export(streamable) {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
log.info(`export geopackage for event ${this._event.id} - ${this._event.name}:\n`, this._filter);
|
|
71
|
+
const downloadedFileName = 'mage-' + this._event.name;
|
|
72
|
+
const archive = (0, archiver_1.default)('zip');
|
|
73
|
+
archive.pipe(streamable);
|
|
74
|
+
try {
|
|
75
|
+
const filePath = yield createGeoPackageFile();
|
|
76
|
+
const gp = yield geopackage_1.GeoPackageAPI.create(filePath);
|
|
77
|
+
yield this.createUserTable(gp);
|
|
78
|
+
yield createUserFeatureTableStyles(gp);
|
|
79
|
+
if (this._filter.exportObservations) {
|
|
80
|
+
yield this.addFormDataToGeoPackage(gp);
|
|
81
|
+
yield this.createFormAttributeTables(gp);
|
|
82
|
+
yield this.createObservationTable(gp);
|
|
83
|
+
this.observationStyles = yield this.createObservationFeatureTableStyles(gp);
|
|
84
|
+
yield this.addObservationsToGeoPackage(gp);
|
|
85
|
+
}
|
|
86
|
+
if (this._filter.exportLocations) {
|
|
87
|
+
yield this.addLocationsToGeoPackage(gp);
|
|
88
|
+
}
|
|
89
|
+
log.info(`export geopackage created: ${filePath}`);
|
|
90
|
+
archive.append(fs_1.default.createReadStream(filePath), { name: downloadedFileName + '.gpkg' });
|
|
91
|
+
archive.on('end', () => {
|
|
92
|
+
log.info(`removing temporary export geopackage file ${filePath}`);
|
|
93
|
+
fs_1.default.unlink(filePath, (err) => {
|
|
94
|
+
if (err) {
|
|
95
|
+
console.warn('error removing temporary geopackage', filePath);
|
|
96
|
+
}
|
|
97
|
+
gp.close();
|
|
98
|
+
});
|
|
71
99
|
});
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
-
log.info('Create Observation Table');
|
|
79
|
-
const columns = [];
|
|
80
|
-
// TODO columns should be the same as KML file
|
|
81
|
-
columns.push({
|
|
82
|
-
name: 'lastModified',
|
|
83
|
-
dataType: 'DATETIME'
|
|
84
|
-
});
|
|
85
|
-
columns.push({
|
|
86
|
-
name: 'timestamp',
|
|
87
|
-
dataType: 'DATETIME'
|
|
88
|
-
});
|
|
89
|
-
columns.push({
|
|
90
|
-
name: 'mageId',
|
|
91
|
-
dataType: 'TEXT'
|
|
92
|
-
});
|
|
93
|
-
columns.push({
|
|
94
|
-
name: 'userId',
|
|
95
|
-
dataType: 'TEXT'
|
|
96
|
-
});
|
|
97
|
-
columns.push({
|
|
98
|
-
name: 'deviceId',
|
|
99
|
-
dataType: 'TEXT'
|
|
100
|
-
});
|
|
101
|
-
columns.push({
|
|
102
|
-
name: 'createdAt',
|
|
103
|
-
dataType: 'DATETIME'
|
|
104
|
-
});
|
|
105
|
-
columns.push({
|
|
106
|
-
name: 'primaryField',
|
|
107
|
-
dataType: 'TEXT'
|
|
108
|
-
});
|
|
109
|
-
columns.push({
|
|
110
|
-
name: 'variantField',
|
|
111
|
-
dataType: 'TEXT'
|
|
112
|
-
});
|
|
113
|
-
yield geopackage.createFeatureTableFromProperties('Observations', columns);
|
|
114
|
-
return geopackage;
|
|
115
|
-
});
|
|
116
|
-
};
|
|
117
|
-
GeoPackage.prototype.createAttachmentTable = function (geopackage) {
|
|
118
|
-
log.info('Create Attachment Table');
|
|
119
|
-
const columns = [{
|
|
120
|
-
name: "name",
|
|
121
|
-
dataType: "TEXT"
|
|
122
|
-
}, {
|
|
123
|
-
name: "size",
|
|
124
|
-
dataType: "REAL"
|
|
125
|
-
}];
|
|
126
|
-
return geopackage.createMediaTable('Attachments', columns);
|
|
127
|
-
};
|
|
128
|
-
GeoPackage.prototype.addUserToUsersTable = function (geopackage, user, usersLastLocation, zoomToEnvelope) {
|
|
129
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
-
log.info(`add user ${user.username} to users table`);
|
|
131
|
-
const geoJson = {
|
|
132
|
-
type: 'Feature',
|
|
133
|
-
geometry: usersLastLocation.geometry,
|
|
134
|
-
properties: {
|
|
135
|
-
timestamp: usersLastLocation.properties.timestamp,
|
|
136
|
-
username: user.username,
|
|
137
|
-
displayName: user.displayName,
|
|
138
|
-
email: user.email,
|
|
139
|
-
phones: user.phones.join(', '),
|
|
140
|
-
userId: user._id.toString()
|
|
100
|
+
archive.finalize();
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
log.error(`error exporting geopackage`, err);
|
|
104
|
+
throw err;
|
|
141
105
|
}
|
|
142
|
-
};
|
|
143
|
-
const userRowId = geopackage.addGeoJSONFeatureToGeoPackage(geoJson, 'Users');
|
|
144
|
-
const iconPath = path.join(environment.userBaseDirectory, user._id.toString(), 'icon');
|
|
145
|
-
let iconBuffer = null;
|
|
146
|
-
try {
|
|
147
|
-
iconBuffer = yield util.promisify(fs.readFile)(iconPath);
|
|
148
|
-
}
|
|
149
|
-
catch (err) {
|
|
150
|
-
log.error(`error reading reading user icon for geopackage export: ${iconPath}`, err);
|
|
151
|
-
return void (0);
|
|
152
|
-
}
|
|
153
|
-
const featureTableStyles = new GeoPackageAPI.FeatureTableStyles(geopackage, 'Users');
|
|
154
|
-
const iconRow = featureTableStyles.getIconDao().newRow();
|
|
155
|
-
iconRow.data = iconBuffer;
|
|
156
|
-
iconRow.contentType = 'image/png';
|
|
157
|
-
iconRow.name = user.username;
|
|
158
|
-
iconRow.description = `Icon for user ${user.username}`;
|
|
159
|
-
iconRow.width = 20;
|
|
160
|
-
iconRow.anchorU = 0.5;
|
|
161
|
-
iconRow.anchorV = 1.0;
|
|
162
|
-
featureTableStyles.setIconDefault(userRowId, iconRow);
|
|
163
|
-
const featureDao = geopackage.getFeatureDao('Users');
|
|
164
|
-
const rtreeIndex = new GeoPackageAPI.RTreeIndex(geopackage, featureDao);
|
|
165
|
-
rtreeIndex.create();
|
|
166
|
-
if (zoomToEnvelope) {
|
|
167
|
-
this.setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
};
|
|
171
|
-
GeoPackage.prototype.createLocationTableForUser = function (geopackage, userId) {
|
|
172
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
173
|
-
const columns = [];
|
|
174
|
-
columns.push({
|
|
175
|
-
name: 'mageId',
|
|
176
|
-
dataType: 'TEXT'
|
|
177
|
-
});
|
|
178
|
-
columns.push({
|
|
179
|
-
name: 'userId',
|
|
180
|
-
dataType: 'TEXT'
|
|
181
|
-
});
|
|
182
|
-
columns.push({
|
|
183
|
-
name: 'timestamp',
|
|
184
|
-
dataType: 'DATETIME'
|
|
185
|
-
});
|
|
186
|
-
columns.push({
|
|
187
|
-
name: 'deviceId',
|
|
188
|
-
dataType: 'TEXT'
|
|
189
106
|
});
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
107
|
+
}
|
|
108
|
+
createObservationTable(geopackage) {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
log.info('create observation table');
|
|
111
|
+
const columns = [];
|
|
112
|
+
// TODO columns should be the same as KML file
|
|
113
|
+
columns.push({
|
|
114
|
+
name: 'lastModified',
|
|
115
|
+
dataType: 'DATETIME'
|
|
116
|
+
});
|
|
117
|
+
columns.push({
|
|
118
|
+
name: 'timestamp',
|
|
119
|
+
dataType: 'DATETIME'
|
|
120
|
+
});
|
|
121
|
+
columns.push({
|
|
122
|
+
name: 'mageId',
|
|
123
|
+
dataType: 'TEXT'
|
|
124
|
+
});
|
|
125
|
+
columns.push({
|
|
126
|
+
name: 'userId',
|
|
127
|
+
dataType: 'TEXT'
|
|
128
|
+
});
|
|
129
|
+
columns.push({
|
|
130
|
+
name: 'deviceId',
|
|
131
|
+
dataType: 'TEXT'
|
|
132
|
+
});
|
|
133
|
+
columns.push({
|
|
134
|
+
name: 'createdAt',
|
|
135
|
+
dataType: 'DATETIME'
|
|
136
|
+
});
|
|
137
|
+
columns.push({
|
|
138
|
+
name: 'primaryField',
|
|
139
|
+
dataType: 'TEXT'
|
|
140
|
+
});
|
|
141
|
+
columns.push({
|
|
142
|
+
name: 'variantField',
|
|
143
|
+
dataType: 'TEXT'
|
|
144
|
+
});
|
|
145
|
+
yield geopackage.createFeatureTableFromProperties('Observations', columns);
|
|
193
146
|
});
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (zoomToEnvelope) {
|
|
211
|
-
//Switching user, so update location
|
|
212
|
-
const featureDao = geopackage.getFeatureDao('Locations_' + user._id.toString());
|
|
213
|
-
this.setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
214
|
-
yield this.addUserToUsersTable(geopackage, user, userLastLocation, zoomToEnvelope);
|
|
215
|
-
}
|
|
216
|
-
zoomToEnvelope = null;
|
|
217
|
-
user = yield User.getUserById(location.userId);
|
|
218
|
-
yield this.createLocationTableForUser(geopackage, location.userId.toString());
|
|
219
|
-
}
|
|
220
|
-
zoomToEnvelope = this.calculateBounds(location.geometry, zoomToEnvelope);
|
|
221
|
-
userLastLocation = location;
|
|
222
|
-
const geojson = {
|
|
147
|
+
}
|
|
148
|
+
createAttachmentTable(geopackage) {
|
|
149
|
+
log.info('create attachment table');
|
|
150
|
+
const columns = [{
|
|
151
|
+
name: "name",
|
|
152
|
+
dataType: "TEXT"
|
|
153
|
+
}, {
|
|
154
|
+
name: "size",
|
|
155
|
+
dataType: "REAL"
|
|
156
|
+
}];
|
|
157
|
+
geopackage.createMediaTable('Attachments', columns);
|
|
158
|
+
}
|
|
159
|
+
addUserToUsersTable(geopackage, user, usersLastLocation, zoomToEnvelope) {
|
|
160
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
161
|
+
log.info(`add user ${user.username} to users table`);
|
|
162
|
+
const feature = {
|
|
223
163
|
type: 'Feature',
|
|
224
|
-
geometry:
|
|
225
|
-
properties:
|
|
164
|
+
geometry: usersLastLocation.geometry,
|
|
165
|
+
properties: {
|
|
166
|
+
timestamp: usersLastLocation.properties.timestamp,
|
|
167
|
+
username: user.username,
|
|
168
|
+
displayName: user.displayName,
|
|
169
|
+
email: user.email,
|
|
170
|
+
phones: user.phones.join(', '),
|
|
171
|
+
userId: user._id.toString()
|
|
172
|
+
}
|
|
226
173
|
};
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
174
|
+
const userRowId = geopackage.addGeoJSONFeatureToGeoPackage(feature, 'Users');
|
|
175
|
+
const iconPath = user.icon.relativePath ? path_1.default.join(env_1.default.userBaseDirectory, user.icon.relativePath) : null;
|
|
176
|
+
if (iconPath) {
|
|
177
|
+
const featureTableStyles = new GPKG.FeatureTableStyles(geopackage, 'Users');
|
|
178
|
+
const iconRow = featureTableStyles.getIconDao().newRow();
|
|
179
|
+
try {
|
|
180
|
+
const iconBuffer = yield promises_1.default.readFile(iconPath);
|
|
181
|
+
iconRow.data = iconBuffer;
|
|
182
|
+
iconRow.contentType = 'image/png';
|
|
183
|
+
iconRow.name = user.username;
|
|
184
|
+
iconRow.description = `Icon for user ${user.username}`;
|
|
185
|
+
iconRow.width = 20;
|
|
186
|
+
iconRow.anchorU = 0.5;
|
|
187
|
+
iconRow.anchorV = 1.0;
|
|
188
|
+
featureTableStyles.setIconDefault(userRowId, iconRow);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
log.error(`error reading user icon for geopackage export: ${iconPath}`, err);
|
|
192
|
+
return void (0);
|
|
193
|
+
}
|
|
232
194
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
if (zoomToEnvelope && user) {
|
|
239
|
-
//Process the last user, since it was missed in the loop above
|
|
240
|
-
const featureDao = geopackage.getFeatureDao('Locations_' + user._id.toString());
|
|
241
|
-
this.setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
242
|
-
yield this.addUserToUsersTable(geopackage, user, userLastLocation, zoomToEnvelope);
|
|
195
|
+
const featureDao = geopackage.getFeatureDao('Users');
|
|
196
|
+
const rtreeIndex = new GPKG.RTreeIndex(geopackage, featureDao);
|
|
197
|
+
rtreeIndex.create();
|
|
198
|
+
if (zoomToEnvelope) {
|
|
199
|
+
setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
243
200
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
});
|
|
249
|
-
};
|
|
250
|
-
GeoPackage.prototype.createFormAttributeTables = function (geopackage) {
|
|
251
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
252
|
-
log.info('Create Form Attribute Tables');
|
|
253
|
-
const formIds = Object.keys(this._event.formMap);
|
|
254
|
-
for (let i = 0; i < formIds.length; i++) {
|
|
255
|
-
const formId = formIds[i];
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
createLocationTableForUser(geopackage, userId) {
|
|
204
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
256
205
|
const columns = [];
|
|
257
|
-
const form = this._event.formMap[formId];
|
|
258
|
-
if (form.primaryField) {
|
|
259
|
-
columns.push({
|
|
260
|
-
name: 'primaryField',
|
|
261
|
-
dataType: 'TEXT'
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
if (form.variantField) {
|
|
265
|
-
columns.push({
|
|
266
|
-
name: 'variantField',
|
|
267
|
-
dataType: 'TEXT'
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
206
|
columns.push({
|
|
271
|
-
name: '
|
|
272
|
-
dataType: '
|
|
273
|
-
|
|
207
|
+
name: 'mageId',
|
|
208
|
+
dataType: 'TEXT'
|
|
209
|
+
});
|
|
210
|
+
columns.push({
|
|
211
|
+
name: 'userId',
|
|
212
|
+
dataType: 'TEXT'
|
|
274
213
|
});
|
|
275
|
-
|
|
276
|
-
|
|
214
|
+
columns.push({
|
|
215
|
+
name: 'timestamp',
|
|
216
|
+
dataType: 'DATETIME'
|
|
217
|
+
});
|
|
218
|
+
columns.push({
|
|
219
|
+
name: 'deviceId',
|
|
220
|
+
dataType: 'TEXT'
|
|
221
|
+
});
|
|
222
|
+
columns.push({
|
|
223
|
+
name: 'accuracy',
|
|
224
|
+
dataType: 'REAL'
|
|
225
|
+
});
|
|
226
|
+
yield geopackage.createFeatureTableFromProperties('Locations_' + userId, columns);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
addLocationsToGeoPackage(geopackage) {
|
|
230
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
231
|
+
log.info('fetching locations');
|
|
232
|
+
const { startDate, endDate } = this._filter;
|
|
233
|
+
const cursor = this.requestLocations({ startDate, endDate });
|
|
234
|
+
let numLocations = 0;
|
|
235
|
+
let user = null;
|
|
236
|
+
let userLastLocation = null;
|
|
237
|
+
let zoomToEnvelope = null;
|
|
238
|
+
return cursor.eachAsync((location) => __awaiter(this, void 0, void 0, function* () {
|
|
239
|
+
if (!user || user._id.toString() !== location.userId.toString()) {
|
|
240
|
+
if (zoomToEnvelope) {
|
|
241
|
+
// Switching user, so update location
|
|
242
|
+
const featureDao = geopackage.getFeatureDao('Locations_' + user._id.toString());
|
|
243
|
+
setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
244
|
+
yield this.addUserToUsersTable(geopackage, user, userLastLocation, zoomToEnvelope);
|
|
245
|
+
}
|
|
246
|
+
zoomToEnvelope = null;
|
|
247
|
+
user = yield user_1.default.getUserById(location.userId);
|
|
248
|
+
yield this.createLocationTableForUser(geopackage, location.userId.toString());
|
|
249
|
+
}
|
|
250
|
+
zoomToEnvelope = calculateBounds(location.geometry, zoomToEnvelope);
|
|
251
|
+
userLastLocation = location;
|
|
252
|
+
const feature = {
|
|
253
|
+
type: 'Feature',
|
|
254
|
+
geometry: location.geometry,
|
|
255
|
+
properties: location.properties
|
|
256
|
+
};
|
|
257
|
+
feature.properties.mageId = location._id.toString();
|
|
258
|
+
feature.properties.userId = location.userId.toString();
|
|
259
|
+
feature.properties.deviceId = location.properties.deviceId.toString();
|
|
260
|
+
if (feature.properties.id) {
|
|
261
|
+
delete feature.properties.id;
|
|
262
|
+
}
|
|
263
|
+
yield geopackage.addGeoJSONFeatureToGeoPackage(feature, 'Locations_' + location.userId.toString());
|
|
264
|
+
numLocations++;
|
|
265
|
+
})).then(() => __awaiter(this, void 0, void 0, function* () {
|
|
266
|
+
if (cursor) {
|
|
267
|
+
cursor.close();
|
|
268
|
+
}
|
|
269
|
+
if (zoomToEnvelope && user) {
|
|
270
|
+
//Process the last user, since it was missed in the loop above
|
|
271
|
+
const featureDao = geopackage.getFeatureDao('Locations_' + user._id.toString());
|
|
272
|
+
setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
273
|
+
yield this.addUserToUsersTable(geopackage, user, userLastLocation, zoomToEnvelope);
|
|
274
|
+
}
|
|
275
|
+
log.info(`wrote ${numLocations} locations to geopackage`);
|
|
276
|
+
}))
|
|
277
|
+
.catch(err => { log.warn(err); });
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
createFormAttributeTables(geopackage) {
|
|
281
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
282
|
+
log.info('create form attribute tables');
|
|
283
|
+
for (const form of this._event.forms) {
|
|
284
|
+
const columns = [];
|
|
285
|
+
if (form.primaryField) {
|
|
286
|
+
columns.push({
|
|
287
|
+
name: 'primaryField',
|
|
288
|
+
dataType: 'TEXT'
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
if (form.variantField) {
|
|
292
|
+
columns.push({
|
|
293
|
+
name: 'variantField',
|
|
294
|
+
dataType: 'TEXT'
|
|
295
|
+
});
|
|
296
|
+
}
|
|
277
297
|
columns.push({
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
name: field.title,
|
|
282
|
-
title: field.title
|
|
283
|
-
},
|
|
284
|
-
name: field.name,
|
|
285
|
-
dataType: this.fieldTypeToGeoPackageType(field.type)
|
|
298
|
+
name: 'formId',
|
|
299
|
+
dataType: 'INTEGER',
|
|
300
|
+
default: form.id
|
|
286
301
|
});
|
|
302
|
+
for (let i = 0; i < form.fields.length; i++) {
|
|
303
|
+
const field = form.fields[i];
|
|
304
|
+
columns.push({
|
|
305
|
+
dataColumn: {
|
|
306
|
+
column_name: field.name,
|
|
307
|
+
table_name: 'Form_' + form.id,
|
|
308
|
+
name: field.title,
|
|
309
|
+
title: field.title
|
|
310
|
+
},
|
|
311
|
+
name: field.name,
|
|
312
|
+
dataType: this.fieldTypeToGeoPackageType(field.type)
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
yield geopackage.createAttributesTableFromProperties('Form_' + form.id, columns);
|
|
287
316
|
}
|
|
288
|
-
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
fieldTypeToGeoPackageType(fieldType) {
|
|
320
|
+
switch (fieldType) {
|
|
321
|
+
case 'numberfield':
|
|
322
|
+
return 'INTEGER';
|
|
323
|
+
case 'attachment':
|
|
324
|
+
case 'textarea':
|
|
325
|
+
case 'textfield':
|
|
326
|
+
return 'TEXT';
|
|
327
|
+
default:
|
|
328
|
+
return 'TEXT';
|
|
289
329
|
}
|
|
290
|
-
return geopackage;
|
|
291
|
-
});
|
|
292
|
-
};
|
|
293
|
-
GeoPackage.prototype.fieldTypeToGeoPackageType = function (fieldType) {
|
|
294
|
-
switch (fieldType) {
|
|
295
|
-
case 'numberfield':
|
|
296
|
-
return 'INTEGER';
|
|
297
|
-
case 'attachment':
|
|
298
|
-
case 'textarea':
|
|
299
|
-
case 'textfield':
|
|
300
|
-
return 'TEXT';
|
|
301
|
-
default:
|
|
302
|
-
return 'TEXT';
|
|
303
330
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
yield geopackage.createMediaTable('UserAvatars');
|
|
335
|
-
return geopackage;
|
|
336
|
-
});
|
|
337
|
-
};
|
|
338
|
-
GeoPackage.prototype.addFormDataToGeoPackage = function (geopackage) {
|
|
339
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
340
|
-
const columns = [];
|
|
341
|
-
columns.push({
|
|
342
|
-
name: 'formName',
|
|
343
|
-
dataType: 'TEXT'
|
|
344
|
-
});
|
|
345
|
-
columns.push({
|
|
346
|
-
name: 'primaryField',
|
|
347
|
-
dataType: 'TEXT'
|
|
348
|
-
});
|
|
349
|
-
columns.push({
|
|
350
|
-
name: 'variantField',
|
|
351
|
-
dataType: 'TEXT'
|
|
352
|
-
});
|
|
353
|
-
columns.push({
|
|
354
|
-
name: 'color',
|
|
355
|
-
dataType: 'TEXT'
|
|
356
|
-
});
|
|
357
|
-
columns.push({
|
|
358
|
-
name: 'formId',
|
|
359
|
-
dataType: 'TEXT'
|
|
331
|
+
createUserTable(geopackage) {
|
|
332
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
333
|
+
const columns = [];
|
|
334
|
+
columns.push({
|
|
335
|
+
name: 'username',
|
|
336
|
+
dataType: 'TEXT'
|
|
337
|
+
});
|
|
338
|
+
columns.push({
|
|
339
|
+
name: 'displayName',
|
|
340
|
+
dataType: 'TEXT'
|
|
341
|
+
});
|
|
342
|
+
columns.push({
|
|
343
|
+
name: 'email',
|
|
344
|
+
dataType: 'TEXT'
|
|
345
|
+
});
|
|
346
|
+
columns.push({
|
|
347
|
+
name: 'phones',
|
|
348
|
+
dataType: 'TEXT'
|
|
349
|
+
});
|
|
350
|
+
columns.push({
|
|
351
|
+
name: 'userId',
|
|
352
|
+
dataType: 'TEXT'
|
|
353
|
+
});
|
|
354
|
+
columns.push({
|
|
355
|
+
name: 'timestamp',
|
|
356
|
+
dataType: 'DATETIME'
|
|
357
|
+
});
|
|
358
|
+
yield geopackage.createFeatureTableFromProperties('Users', columns);
|
|
359
|
+
log.info('create user avatar table');
|
|
360
|
+
yield geopackage.createMediaTable('UserAvatars', void (0) /* really is optional */);
|
|
360
361
|
});
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
timestamp: observation.properties.timestamp,
|
|
396
|
-
mageId: observation._id.toString(),
|
|
397
|
-
createdAt: observation.createdAt,
|
|
398
|
-
primaryField: primary,
|
|
399
|
-
variantField: variant
|
|
400
|
-
};
|
|
401
|
-
if (observation.userId) {
|
|
402
|
-
properties.userId = observation.userId.toString();
|
|
403
|
-
}
|
|
404
|
-
if (observation.deviceId) {
|
|
405
|
-
properties.deviceId = observation.deviceId.toString();
|
|
362
|
+
}
|
|
363
|
+
addFormDataToGeoPackage(geopackage) {
|
|
364
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
365
|
+
const columns = [];
|
|
366
|
+
columns.push({
|
|
367
|
+
name: 'formName',
|
|
368
|
+
dataType: 'TEXT'
|
|
369
|
+
});
|
|
370
|
+
columns.push({
|
|
371
|
+
name: 'primaryField',
|
|
372
|
+
dataType: 'TEXT'
|
|
373
|
+
});
|
|
374
|
+
columns.push({
|
|
375
|
+
name: 'variantField',
|
|
376
|
+
dataType: 'TEXT'
|
|
377
|
+
});
|
|
378
|
+
columns.push({
|
|
379
|
+
name: 'color',
|
|
380
|
+
dataType: 'TEXT'
|
|
381
|
+
});
|
|
382
|
+
columns.push({
|
|
383
|
+
name: 'formId',
|
|
384
|
+
dataType: 'TEXT'
|
|
385
|
+
});
|
|
386
|
+
yield geopackage.createAttributesTableFromProperties('Forms', columns);
|
|
387
|
+
for (const form of this._event.forms) {
|
|
388
|
+
const row = {
|
|
389
|
+
formName: form.name,
|
|
390
|
+
primaryField: form.primaryField || null,
|
|
391
|
+
variantField: form.variantField || null,
|
|
392
|
+
color: form.color,
|
|
393
|
+
formId: form.id
|
|
394
|
+
};
|
|
395
|
+
geopackage.addAttributeRow('Forms', row);
|
|
406
396
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
addObservationsToGeoPackage(geopackage) {
|
|
400
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
401
|
+
log.info('requesting locations from db');
|
|
402
|
+
this.createAttachmentTable(geopackage);
|
|
403
|
+
const cursor = this.requestObservations(this._filter);
|
|
404
|
+
let numObservations = 0;
|
|
405
|
+
let zoomToEnvelope;
|
|
406
|
+
return cursor.eachAsync((observation) => __awaiter(this, void 0, void 0, function* () {
|
|
407
|
+
console.debug('exporting observation', observation.id, '...');
|
|
408
|
+
numObservations++;
|
|
409
|
+
if (!Array.isArray(observation.properties.forms)) {
|
|
410
|
+
return;
|
|
419
411
|
}
|
|
420
|
-
|
|
421
|
-
|
|
412
|
+
const primaryEntry = observation.properties.forms[0];
|
|
413
|
+
if (!primaryEntry) {
|
|
414
|
+
return;
|
|
422
415
|
}
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
416
|
+
const form = this._event.formFor(primaryEntry.formId);
|
|
417
|
+
const primary = (form === null || form === void 0 ? void 0 : form.primaryField) ? String(primaryEntry[form.primaryField]) : null;
|
|
418
|
+
const variant = (form === null || form === void 0 ? void 0 : form.primaryField) && (form === null || form === void 0 ? void 0 : form.variantField) ? String(primaryEntry[form.variantField]) : null;
|
|
419
|
+
const properties = {
|
|
420
|
+
lastModified: observation.lastModified,
|
|
421
|
+
timestamp: observation.properties.timestamp,
|
|
422
|
+
mageId: observation._id.toString(),
|
|
423
|
+
createdAt: observation.createdAt,
|
|
424
|
+
primaryField: primary,
|
|
425
|
+
variantField: variant
|
|
426
|
+
};
|
|
427
|
+
if (observation.userId) {
|
|
428
|
+
properties.userId = observation.userId.toString();
|
|
429
|
+
}
|
|
430
|
+
if (observation.deviceId) {
|
|
431
|
+
properties.deviceId = observation.deviceId.toString();
|
|
432
|
+
}
|
|
433
|
+
const feature = {
|
|
434
|
+
type: 'Feature',
|
|
435
|
+
geometry: observation.geometry,
|
|
436
|
+
properties
|
|
437
|
+
};
|
|
438
|
+
zoomToEnvelope = calculateBounds(feature.geometry, zoomToEnvelope);
|
|
439
|
+
const featureId = geopackage.addGeoJSONFeatureToGeoPackage(feature, 'Observations');
|
|
440
|
+
const iconSpec = {
|
|
441
|
+
eventId: this._event.id,
|
|
442
|
+
formId: primaryEntry.formId,
|
|
443
|
+
primary,
|
|
444
|
+
variant,
|
|
445
|
+
};
|
|
446
|
+
yield this.linkObservationFeatureIcon(iconSpec, featureId);
|
|
447
|
+
const formEntries = observation.properties.forms || [];
|
|
448
|
+
for (const formEntry of formEntries) {
|
|
449
|
+
const form = this._event.formFor(formEntry.formId);
|
|
450
|
+
const primary = form.primaryField ? String(formEntry[form.primaryField]) : null;
|
|
451
|
+
const variant = form.primaryField && form.variantField ? String(formEntry[form.variantField]) : null;
|
|
432
452
|
const formToSave = {
|
|
433
453
|
primaryField: primary,
|
|
434
454
|
variantField: variant,
|
|
435
|
-
formId:
|
|
455
|
+
formId: formEntry.formId
|
|
436
456
|
};
|
|
437
457
|
const attachments = [];
|
|
438
458
|
if (observation.attachments) {
|
|
439
459
|
observation.attachments.forEach((attachment) => {
|
|
440
|
-
if (attachment.observationFormId
|
|
460
|
+
if (String(attachment.observationFormId) === String(formEntry._id)) {
|
|
441
461
|
attachments.push(attachment);
|
|
442
|
-
|
|
443
|
-
|
|
462
|
+
const attachmentFieldEntries = (formEntry[attachment.fieldName] || []);
|
|
463
|
+
attachmentFieldEntries.push(String(attachment._id));
|
|
464
|
+
formEntry[attachment.fieldName] = attachmentFieldEntries;
|
|
444
465
|
}
|
|
445
466
|
});
|
|
446
467
|
}
|
|
447
|
-
Object.keys(
|
|
448
|
-
|
|
468
|
+
Object.keys(formEntry).forEach(key => {
|
|
469
|
+
const fieldEntry = formEntry[key];
|
|
470
|
+
if (fieldEntry === null || fieldEntry === undefined) {
|
|
449
471
|
return;
|
|
450
|
-
|
|
451
|
-
|
|
472
|
+
}
|
|
473
|
+
const field = this._event.formFieldFor(key, form.id);
|
|
474
|
+
if (!field) {
|
|
452
475
|
return;
|
|
453
|
-
if (fieldDefinition.type === 'multiselectdropdown') {
|
|
454
|
-
formToSave[key] = observationForm[key].join(', ');
|
|
455
476
|
}
|
|
456
|
-
|
|
457
|
-
formToSave[key] =
|
|
477
|
+
if (field.type === 'multiselectdropdown') {
|
|
478
|
+
formToSave[key] = fieldEntry.join(', ');
|
|
458
479
|
}
|
|
459
|
-
else if (
|
|
460
|
-
formToSave[key] =
|
|
480
|
+
else if (field.type === 'date') {
|
|
481
|
+
formToSave[key] = (0, moment_1.default)(fieldEntry).toISOString();
|
|
461
482
|
}
|
|
462
|
-
else if (
|
|
463
|
-
formToSave[key] =
|
|
483
|
+
else if (field.type === 'checkbox') {
|
|
484
|
+
formToSave[key] = String(fieldEntry);
|
|
464
485
|
}
|
|
465
|
-
else if (
|
|
466
|
-
formToSave[key] =
|
|
486
|
+
else if (field.type === 'geometry') {
|
|
487
|
+
formToSave[key] = wkx_1.default.Geometry.parseGeoJSON(fieldEntry).toWkt();
|
|
488
|
+
}
|
|
489
|
+
else if (field.type === 'attachment') {
|
|
490
|
+
formToSave[key] = fieldEntry.join(', ');
|
|
467
491
|
}
|
|
468
492
|
else {
|
|
469
|
-
formToSave[key] =
|
|
493
|
+
formToSave[key] = fieldEntry;
|
|
470
494
|
}
|
|
471
495
|
});
|
|
472
496
|
try {
|
|
473
497
|
const rowId = geopackage.addAttributeRow('Form_' + formToSave.formId, formToSave);
|
|
474
498
|
if (attachments.length) {
|
|
475
|
-
yield
|
|
499
|
+
yield addAttachments(geopackage, attachments, featureId, 'Form_' + formToSave.formId, rowId);
|
|
476
500
|
}
|
|
477
|
-
yield geopackage.linkRelatedRows('Observations', featureId, 'Form_' + formToSave.formId, rowId, RelationType.ATTRIBUTES);
|
|
501
|
+
yield geopackage.linkRelatedRows('Observations', featureId, 'Form_' + formToSave.formId, rowId, relationType_1.RelationType.ATTRIBUTES);
|
|
478
502
|
}
|
|
479
503
|
catch (e) {
|
|
480
|
-
|
|
504
|
+
log.error(`error writing rows for form entry ${formEntry.id} of observation ${observation.id} to geopackage`, e);
|
|
481
505
|
}
|
|
482
506
|
}
|
|
507
|
+
}))
|
|
508
|
+
.then(() => __awaiter(this, void 0, void 0, function* () {
|
|
509
|
+
if (cursor) {
|
|
510
|
+
yield cursor.close();
|
|
511
|
+
}
|
|
512
|
+
const featureDao = geopackage.getFeatureDao('Observations');
|
|
513
|
+
const rtreeIndex = new GPKG.RTreeIndex(geopackage, featureDao);
|
|
514
|
+
rtreeIndex.create();
|
|
515
|
+
if (zoomToEnvelope) {
|
|
516
|
+
setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
517
|
+
}
|
|
518
|
+
log.info(`'wrote ${numObservations} observations to geopackage`);
|
|
519
|
+
}))
|
|
520
|
+
.catch(err => {
|
|
521
|
+
log.warn(err);
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
createObservationFeatureTableStyles(geopackage) {
|
|
526
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
527
|
+
const featureTableName = 'Observations';
|
|
528
|
+
const featureTableStyles = new GPKG.FeatureTableStyles(geopackage, featureTableName);
|
|
529
|
+
yield geopackage.featureStyleExtension.getOrCreateExtension(featureTableName);
|
|
530
|
+
yield geopackage.featureStyleExtension.getRelatedTables().getOrCreateExtension();
|
|
531
|
+
yield geopackage.featureStyleExtension.getContentsId().getOrCreateExtension();
|
|
532
|
+
featureTableStyles.createRelationships();
|
|
533
|
+
const defaultIconAccess = new api_1.default.Icon(this._event.id);
|
|
534
|
+
const defaultIconDoc = yield util_1.default.promisify(defaultIconAccess.getIcon.bind(defaultIconAccess))();
|
|
535
|
+
if (!defaultIconDoc || isNothing(defaultIconDoc.path)) {
|
|
536
|
+
return featureTableStyles;
|
|
483
537
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
this.setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
538
|
+
try {
|
|
539
|
+
const iconBytes = yield promises_1.default.readFile(defaultIconDoc.path);
|
|
540
|
+
const gpkgIconRow = featureTableStyles.getIconDao().newRow();
|
|
541
|
+
gpkgIconRow.data = iconBytes;
|
|
542
|
+
populateGpkgIconRow(gpkgIconRow, defaultIconDoc, this._event);
|
|
543
|
+
featureTableStyles.setTableIconDefault(gpkgIconRow);
|
|
544
|
+
this.iconCache.put(defaultIconDoc, gpkgIconRow.id);
|
|
492
545
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
546
|
+
catch (err) {
|
|
547
|
+
console.warn('error setting default icon', defaultIconDoc.path);
|
|
548
|
+
}
|
|
549
|
+
return featureTableStyles;
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
linkObservationFeatureIcon(iconSpec, featureId) {
|
|
553
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
554
|
+
const iconId = yield this.ensureIconInGeopackage(iconSpec);
|
|
555
|
+
if (iconId === null) {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
const styleExt = this.observationStyles.getFeatureStyleExtension();
|
|
559
|
+
const iconMappingDao = this.observationStyles.getIconMappingDao();
|
|
560
|
+
styleExt.insertStyleMapping(iconMappingDao, featureId, iconId);
|
|
561
|
+
});
|
|
503
562
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
563
|
+
ensureIconInGeopackage(iconSpec) {
|
|
564
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
565
|
+
const cachedIconId = this.iconCache.get(iconSpec);
|
|
566
|
+
if (cachedIconId === IconTreeCache.ICON_LOAD_ERROR) {
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
if (cachedIconId !== null) {
|
|
570
|
+
return cachedIconId;
|
|
571
|
+
}
|
|
572
|
+
const iconAccess = new api_1.default.Icon(this._event.id, iconSpec.formId, iconSpec.primary, iconSpec.variant);
|
|
573
|
+
const iconDoc = yield util_1.default.promisify(iconAccess.getIcon.bind(iconAccess))();
|
|
574
|
+
if (!iconDoc || isNothing(iconDoc.path)) {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
try {
|
|
578
|
+
const iconBytes = yield promises_1.default.readFile(iconDoc.path);
|
|
579
|
+
const gpkgIconRow = this.observationStyles.getIconDao().newRow();
|
|
580
|
+
gpkgIconRow.data = iconBytes;
|
|
581
|
+
populateGpkgIconRow(gpkgIconRow, iconDoc, this._event);
|
|
582
|
+
const id = this.observationStyles.getIconDao().create(gpkgIconRow);
|
|
583
|
+
this.iconCache.put(iconDoc, id);
|
|
584
|
+
return id;
|
|
585
|
+
}
|
|
586
|
+
catch (err) {
|
|
587
|
+
console.warn('error adding icon', iconDoc.path, err);
|
|
588
|
+
}
|
|
589
|
+
this.iconCache.put(iconDoc, IconTreeCache.ICON_LOAD_ERROR);
|
|
590
|
+
return null;
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
exports.GeoPackage = GeoPackage;
|
|
595
|
+
function populateGpkgIconRow(gpkgIconRow, iconDoc, mageEvent) {
|
|
596
|
+
gpkgIconRow.contentType = 'image/png';
|
|
597
|
+
gpkgIconRow.width = 20;
|
|
598
|
+
gpkgIconRow.anchorU = 0.5;
|
|
599
|
+
gpkgIconRow.anchorV = 1.0;
|
|
600
|
+
const defaultName = `${mageEvent.name} default`;
|
|
601
|
+
const name = (() => {
|
|
602
|
+
if (isNothing(iconDoc.formId)) {
|
|
603
|
+
if (isNothing(iconDoc.primary)) {
|
|
604
|
+
if (isNothing(iconDoc.variant)) {
|
|
605
|
+
return defaultName;
|
|
606
|
+
}
|
|
607
|
+
return iconDoc.variant;
|
|
608
|
+
}
|
|
609
|
+
return iconDoc.primary;
|
|
507
610
|
}
|
|
508
|
-
|
|
509
|
-
|
|
611
|
+
const form = mageEvent.formFor(iconDoc.formId);
|
|
612
|
+
if (!form) {
|
|
613
|
+
return defaultName;
|
|
510
614
|
}
|
|
511
|
-
|
|
512
|
-
|
|
615
|
+
return `${form.name} icon`;
|
|
616
|
+
})();
|
|
617
|
+
gpkgIconRow.name = name;
|
|
618
|
+
return gpkgIconRow;
|
|
619
|
+
}
|
|
620
|
+
function isNothing(wut) {
|
|
621
|
+
return wut === null || wut === undefined || wut === '' || (typeof wut === 'number' && isNaN(wut));
|
|
622
|
+
}
|
|
623
|
+
class IconTreeCache {
|
|
624
|
+
constructor() {
|
|
625
|
+
this.root = new IconTreeCacheNode();
|
|
626
|
+
}
|
|
627
|
+
get(icon) {
|
|
628
|
+
const { formId, primary, variant } = icon;
|
|
629
|
+
if (!isNothing(formId)) {
|
|
630
|
+
const formNode = this.root.children[formId];
|
|
631
|
+
if (formNode) {
|
|
632
|
+
if (!isNothing(primary)) {
|
|
633
|
+
const primaryNode = formNode.children[primary];
|
|
634
|
+
if (primaryNode) {
|
|
635
|
+
if (!isNothing(variant)) {
|
|
636
|
+
const variantNode = primaryNode.children[variant];
|
|
637
|
+
return (variantNode === null || variantNode === void 0 ? void 0 : variantNode.gpkgIconId) || null;
|
|
638
|
+
}
|
|
639
|
+
return primaryNode.gpkgIconId;
|
|
640
|
+
}
|
|
641
|
+
return null;
|
|
642
|
+
}
|
|
643
|
+
return formNode.gpkgIconId;
|
|
644
|
+
}
|
|
645
|
+
return null;
|
|
513
646
|
}
|
|
514
|
-
|
|
515
|
-
|
|
647
|
+
return this.root.gpkgIconId;
|
|
648
|
+
}
|
|
649
|
+
put(icon, gpkgIconId) {
|
|
650
|
+
const node = this.ensurePathNodes(icon);
|
|
651
|
+
node.gpkgIconId = gpkgIconId;
|
|
652
|
+
return this;
|
|
653
|
+
}
|
|
654
|
+
ensurePathNodes(path) {
|
|
655
|
+
const { formId, primary, variant } = path;
|
|
656
|
+
if (!isNothing(formId)) {
|
|
657
|
+
const formNode = this.root.children[formId] = this.root.children[formId] || new IconTreeCacheNode();
|
|
658
|
+
if (!isNothing(primary)) {
|
|
659
|
+
const primaryNode = formNode.children[primary] = formNode.children[primary] || new IconTreeCacheNode();
|
|
660
|
+
if (!isNothing(variant)) {
|
|
661
|
+
return primaryNode.children[variant] = primaryNode.children[variant] || new IconTreeCacheNode();
|
|
662
|
+
}
|
|
663
|
+
return primaryNode;
|
|
664
|
+
}
|
|
665
|
+
return formNode;
|
|
516
666
|
}
|
|
667
|
+
return this.root;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
IconTreeCache.ICON_LOAD_ERROR = Number.MIN_SAFE_INTEGER;
|
|
671
|
+
class IconTreeCacheNode {
|
|
672
|
+
constructor(gpkgRowId = null, children = {}) {
|
|
673
|
+
this.gpkgIconId = null;
|
|
674
|
+
this.gpkgIconId = isNothing(gpkgRowId) ? null : gpkgRowId;
|
|
675
|
+
this.children = children;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
function createGeoPackageFile() {
|
|
679
|
+
const filename = (0, moment_1.default)().format('YYYMMDD_hhmmssSSS') + '.gpkg';
|
|
680
|
+
const filePath = path_1.default.join(os_1.default.tmpdir(), filename);
|
|
681
|
+
return new Promise(function (resolve, reject) {
|
|
682
|
+
fs_1.default.unlink(filePath, function () {
|
|
683
|
+
fs_1.default.mkdir(path_1.default.dirname(filePath), function () {
|
|
684
|
+
fs_1.default.open(filePath, 'w', function (err) {
|
|
685
|
+
if (err)
|
|
686
|
+
return reject(err);
|
|
687
|
+
resolve(filePath);
|
|
688
|
+
});
|
|
689
|
+
});
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
function calculateBounds(geometry, zoomToEnvelope) {
|
|
694
|
+
const wkxGeometry = wkx_1.default.Geometry.parseGeoJSON(geometry);
|
|
695
|
+
const envelope = envelopeBuilder_1.EnvelopeBuilder.buildEnvelopeWithGeometry(wkxGeometry);
|
|
696
|
+
if (!zoomToEnvelope) {
|
|
697
|
+
return envelope;
|
|
698
|
+
}
|
|
699
|
+
if (zoomToEnvelope.maxX < envelope.maxX) {
|
|
700
|
+
zoomToEnvelope.maxX = envelope.maxX;
|
|
701
|
+
}
|
|
702
|
+
if (zoomToEnvelope.maxY < envelope.maxY) {
|
|
703
|
+
zoomToEnvelope.maxY = envelope.maxY;
|
|
704
|
+
}
|
|
705
|
+
if (zoomToEnvelope.minX > envelope.minX) {
|
|
706
|
+
zoomToEnvelope.minX = envelope.minX;
|
|
707
|
+
}
|
|
708
|
+
if (zoomToEnvelope.minY > envelope.minY) {
|
|
709
|
+
zoomToEnvelope.minY = envelope.minY;
|
|
517
710
|
}
|
|
518
711
|
return zoomToEnvelope;
|
|
519
|
-
}
|
|
520
|
-
|
|
712
|
+
}
|
|
713
|
+
function addAttachments(geopackage, attachments, observationId, formTable, formRowId) {
|
|
521
714
|
return __awaiter(this, void 0, void 0, function* () {
|
|
522
|
-
log.info('
|
|
715
|
+
log.info('add attachments');
|
|
523
716
|
for (let i = 0; i < attachments.length; i++) {
|
|
524
717
|
const attachment = attachments[i];
|
|
525
718
|
if (attachment.relativePath) {
|
|
526
719
|
yield new Promise(function (resolve, reject) {
|
|
527
|
-
|
|
528
|
-
if (err)
|
|
720
|
+
fs_1.default.readFile(path_1.default.join(attachmentBase, attachment.relativePath), (err, dataBuffer) => __awaiter(this, void 0, void 0, function* () {
|
|
721
|
+
if (err) {
|
|
529
722
|
return reject(err);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
723
|
+
}
|
|
724
|
+
const mediaId = geopackage.addMedia('Attachments', dataBuffer, attachment.contentType || 'application/octet-stream', {
|
|
725
|
+
name: attachment.name || attachment._id,
|
|
726
|
+
size: attachment.size || 0
|
|
533
727
|
});
|
|
534
728
|
yield geopackage.linkMedia('Observations', observationId, 'Attachments', mediaId);
|
|
535
729
|
resolve(geopackage.linkMedia(formTable, formRowId, 'Attachments', mediaId));
|
|
@@ -538,144 +732,18 @@ GeoPackage.prototype.addAttachments = function (geopackage, attachments, observa
|
|
|
538
732
|
}
|
|
539
733
|
}
|
|
540
734
|
});
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
544
|
-
const featureTableName = 'Observations';
|
|
545
|
-
const featureTableStyles = new GeoPackageAPI.FeatureTableStyles(geopackage, featureTableName);
|
|
546
|
-
yield geopackage.featureStyleExtension.getOrCreateExtension(featureTableName);
|
|
547
|
-
yield geopackage.featureStyleExtension.getRelatedTables().getOrCreateExtension();
|
|
548
|
-
yield geopackage.featureStyleExtension.getContentsId().getOrCreateExtension();
|
|
549
|
-
featureTableStyles.createRelationships();
|
|
550
|
-
yield this.addObservationIcons(geopackage, featureTableStyles);
|
|
551
|
-
return geopackage;
|
|
552
|
-
});
|
|
553
|
-
};
|
|
554
|
-
GeoPackage.prototype.createUserFeatureTableStyles = function (geopackage) {
|
|
735
|
+
}
|
|
736
|
+
function createUserFeatureTableStyles(geopackage) {
|
|
555
737
|
return __awaiter(this, void 0, void 0, function* () {
|
|
556
738
|
const featureTableName = 'Users';
|
|
557
|
-
const featureTableStyles = new
|
|
739
|
+
const featureTableStyles = new GPKG.FeatureTableStyles(geopackage, featureTableName);
|
|
558
740
|
yield geopackage.featureStyleExtension.getOrCreateExtension(featureTableName);
|
|
559
741
|
yield geopackage.featureStyleExtension.getRelatedTables().getOrCreateExtension();
|
|
560
742
|
yield geopackage.featureStyleExtension.getContentsId().getOrCreateExtension();
|
|
561
743
|
featureTableStyles.createRelationships();
|
|
562
|
-
return geopackage;
|
|
563
744
|
});
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
567
|
-
const rootDir = path.join(new api.Icon(this._event._id).getBasePath());
|
|
568
|
-
if (!fs.existsSync(path.join(rootDir))) {
|
|
569
|
-
return geopackage;
|
|
570
|
-
}
|
|
571
|
-
const formDirs = fs.readdirSync(path.join(rootDir));
|
|
572
|
-
for (let i = 0; i < formDirs.length; i++) {
|
|
573
|
-
const formDir = formDirs[i];
|
|
574
|
-
this.iconMap[formDir] = this.iconMap[formDir] || {};
|
|
575
|
-
if (!fs.existsSync(path.join(rootDir, formDir))) {
|
|
576
|
-
continue;
|
|
577
|
-
}
|
|
578
|
-
if (formDir === 'icon.png') {
|
|
579
|
-
yield new Promise((resolve, reject) => {
|
|
580
|
-
fs.readFile(path.join(rootDir, formDir), (err, iconBuffer) => __awaiter(this, void 0, void 0, function* () {
|
|
581
|
-
if (err)
|
|
582
|
-
return reject(err);
|
|
583
|
-
const iconRow = featureTableStyles.getIconDao().newRow();
|
|
584
|
-
iconRow.data = iconBuffer;
|
|
585
|
-
iconRow.contentType = 'image/png';
|
|
586
|
-
iconRow.name = `${this._event.name} icon`;
|
|
587
|
-
iconRow.description = `Icon for event ${this._event.name}`;
|
|
588
|
-
iconRow.width = 20;
|
|
589
|
-
iconRow.anchorU = 0.5;
|
|
590
|
-
iconRow.anchorV = 1.0;
|
|
591
|
-
this.iconMap[formDir] = iconRow;
|
|
592
|
-
yield featureTableStyles.setTableIconDefault(iconRow);
|
|
593
|
-
resolve();
|
|
594
|
-
}));
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
else {
|
|
598
|
-
const primaryDirs = fs.readdirSync(path.join(rootDir, formDir));
|
|
599
|
-
for (let p = 0; p < primaryDirs.length; p++) {
|
|
600
|
-
const primaryDir = primaryDirs[p];
|
|
601
|
-
if (!fs.existsSync(path.join(rootDir, formDir, primaryDir))) {
|
|
602
|
-
continue;
|
|
603
|
-
}
|
|
604
|
-
if (primaryDir === 'icon.png') {
|
|
605
|
-
yield new Promise((resolve, reject) => {
|
|
606
|
-
fs.readFile(path.join(rootDir, formDir, primaryDir), (err, iconBuffer) => {
|
|
607
|
-
if (err)
|
|
608
|
-
return reject(err);
|
|
609
|
-
const iconRow = featureTableStyles.getIconDao().newRow();
|
|
610
|
-
iconRow.data = iconBuffer;
|
|
611
|
-
iconRow.contentType = 'image/png';
|
|
612
|
-
iconRow.name = formDir;
|
|
613
|
-
iconRow.description = `Icon for form ${formDir}/icon.png`;
|
|
614
|
-
iconRow.width = 20;
|
|
615
|
-
iconRow.anchorU = 0.5;
|
|
616
|
-
iconRow.anchorV = 1.0;
|
|
617
|
-
this.iconMap[formDir]['icon.png'] = iconRow;
|
|
618
|
-
resolve();
|
|
619
|
-
});
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
else {
|
|
623
|
-
this.iconMap[formDir][primaryDir] = this.iconMap[formDir][primaryDir] || {};
|
|
624
|
-
const variantDirs = fs.readdirSync(path.join(rootDir, formDir, primaryDir));
|
|
625
|
-
for (let v = 0; v < variantDirs.length; v++) {
|
|
626
|
-
const variantDir = variantDirs[v];
|
|
627
|
-
if (!fs.existsSync(path.join(rootDir, formDir, primaryDir, variantDir))) {
|
|
628
|
-
continue;
|
|
629
|
-
}
|
|
630
|
-
if (variantDir === 'icon.png') {
|
|
631
|
-
yield new Promise((resolve, reject) => {
|
|
632
|
-
fs.readFile(path.join(rootDir, formDir, primaryDir, variantDir), (err, iconBuffer) => {
|
|
633
|
-
if (err)
|
|
634
|
-
return reject(err);
|
|
635
|
-
const iconRow = featureTableStyles.getIconDao().newRow();
|
|
636
|
-
iconRow.data = iconBuffer;
|
|
637
|
-
iconRow.contentType = 'image/png';
|
|
638
|
-
iconRow.name = primaryDir;
|
|
639
|
-
iconRow.description = `Icon for form ${formDir}/${primaryDir}/icon.png`;
|
|
640
|
-
iconRow.width = 20;
|
|
641
|
-
iconRow.anchorU = 0.5;
|
|
642
|
-
iconRow.anchorV = 1.0;
|
|
643
|
-
this.iconMap[formDir][primaryDir]['icon.png'] = iconRow;
|
|
644
|
-
resolve();
|
|
645
|
-
});
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
else {
|
|
649
|
-
this.iconMap[formDir][primaryDir][variantDir] = this.iconMap[formDir][primaryDir][variantDir] || {};
|
|
650
|
-
if (!fs.existsSync(path.join(rootDir, formDir, primaryDir, variantDir, 'icon.png'))) {
|
|
651
|
-
continue;
|
|
652
|
-
}
|
|
653
|
-
yield new Promise((resolve, reject) => {
|
|
654
|
-
fs.readFile(path.join(rootDir, formDir, primaryDir, variantDir, 'icon.png'), (err, iconBuffer) => {
|
|
655
|
-
if (err)
|
|
656
|
-
return reject(err);
|
|
657
|
-
const iconRow = featureTableStyles.getIconDao().newRow();
|
|
658
|
-
iconRow.data = iconBuffer;
|
|
659
|
-
iconRow.contentType = 'image/png';
|
|
660
|
-
iconRow.name = variantDir;
|
|
661
|
-
iconRow.description = `Icon for form ${formDir}/${primaryDir}/${variantDir}/icon.png`;
|
|
662
|
-
iconRow.width = 20;
|
|
663
|
-
iconRow.anchorU = 0.5;
|
|
664
|
-
iconRow.anchorV = 1.0;
|
|
665
|
-
this.iconMap[formDir][primaryDir][variantDir]['icon.png'] = iconRow;
|
|
666
|
-
resolve();
|
|
667
|
-
});
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
return geopackage;
|
|
676
|
-
});
|
|
677
|
-
};
|
|
678
|
-
GeoPackage.prototype.setContentBounds = function (geopackage, featureDao, zoomToEnvelope) {
|
|
745
|
+
}
|
|
746
|
+
function setContentBounds(geopackage, featureDao, zoomToEnvelope) {
|
|
679
747
|
const contents = featureDao.getContents();
|
|
680
748
|
contents.max_x = zoomToEnvelope.maxX;
|
|
681
749
|
contents.max_y = zoomToEnvelope.maxY;
|
|
@@ -683,5 +751,5 @@ GeoPackage.prototype.setContentBounds = function (geopackage, featureDao, zoomTo
|
|
|
683
751
|
contents.min_y = zoomToEnvelope.minY;
|
|
684
752
|
const contentsDao = geopackage.contentsDao;
|
|
685
753
|
contentsDao.update(contents);
|
|
686
|
-
}
|
|
754
|
+
}
|
|
687
755
|
//# sourceMappingURL=geopackage.js.map
|