@ngageoint/mage.service 6.2.9 → 6.2.10-beta.2
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.js +2 -2
- package/lib/adapters/observations/adapters.observations.controllers.web.js.map +1 -1
- package/lib/adapters/observations/adapters.observations.dto.ecma404-json.d.ts +1 -1
- package/lib/adapters/observations/adapters.observations.dto.ecma404-json.js +1 -1
- 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/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 +2 -1
- 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 +45 -45
- 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 +4 -4
- package/lib/entities/observations/entities.observations.d.ts.map +1 -1
- package/lib/entities/observations/entities.observations.js +16 -15
- 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 -231
- 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 +659 -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 +27 -0
- 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 +4411 -7493
- package/package.json +45 -45
- 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,701 @@ 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
|
+
var _a;
|
|
240
|
+
if (!user || user._id.toString() !== location.userId.toString()) {
|
|
241
|
+
if (zoomToEnvelope) {
|
|
242
|
+
// Switching user, so update location
|
|
243
|
+
const featureDao = geopackage.getFeatureDao('Locations_' + user._id.toString());
|
|
244
|
+
setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
245
|
+
yield this.addUserToUsersTable(geopackage, user, userLastLocation, zoomToEnvelope);
|
|
246
|
+
}
|
|
247
|
+
zoomToEnvelope = null;
|
|
248
|
+
user = yield user_1.default.getUserById(location.userId);
|
|
249
|
+
yield this.createLocationTableForUser(geopackage, location.userId.toString());
|
|
250
|
+
}
|
|
251
|
+
zoomToEnvelope = calculateBounds(location.geometry, zoomToEnvelope);
|
|
252
|
+
userLastLocation = location;
|
|
253
|
+
const properties = location.properties || {};
|
|
254
|
+
const feature = {
|
|
255
|
+
type: 'Feature',
|
|
256
|
+
geometry: location.geometry,
|
|
257
|
+
properties
|
|
258
|
+
};
|
|
259
|
+
feature.properties.mageId = location._id.toString();
|
|
260
|
+
feature.properties.userId = (_a = location.userId) === null || _a === void 0 ? void 0 : _a.toString();
|
|
261
|
+
feature.properties.deviceId = properties.deviceId ? properties.deviceId.toString() : undefined;
|
|
262
|
+
if (feature.properties.id) {
|
|
263
|
+
delete feature.properties.id;
|
|
264
|
+
}
|
|
265
|
+
yield geopackage.addGeoJSONFeatureToGeoPackage(feature, 'Locations_' + location.userId.toString());
|
|
266
|
+
numLocations++;
|
|
267
|
+
})).then(() => __awaiter(this, void 0, void 0, function* () {
|
|
268
|
+
if (cursor) {
|
|
269
|
+
cursor.close();
|
|
270
|
+
}
|
|
271
|
+
if (zoomToEnvelope && user) {
|
|
272
|
+
//Process the last user, since it was missed in the loop above
|
|
273
|
+
const featureDao = geopackage.getFeatureDao('Locations_' + user._id.toString());
|
|
274
|
+
setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
275
|
+
yield this.addUserToUsersTable(geopackage, user, userLastLocation, zoomToEnvelope);
|
|
276
|
+
}
|
|
277
|
+
log.info(`wrote ${numLocations} locations to geopackage`);
|
|
278
|
+
}))
|
|
279
|
+
.catch(err => { log.warn(err); });
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
createFormAttributeTables(geopackage) {
|
|
283
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
284
|
+
log.info('create form attribute tables');
|
|
285
|
+
for (const form of this._event.forms) {
|
|
286
|
+
const columns = [];
|
|
287
|
+
if (form.primaryField) {
|
|
288
|
+
columns.push({
|
|
289
|
+
name: 'primaryField',
|
|
290
|
+
dataType: 'TEXT'
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (form.variantField) {
|
|
294
|
+
columns.push({
|
|
295
|
+
name: 'variantField',
|
|
296
|
+
dataType: 'TEXT'
|
|
297
|
+
});
|
|
298
|
+
}
|
|
277
299
|
columns.push({
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
name: field.title,
|
|
282
|
-
title: field.title
|
|
283
|
-
},
|
|
284
|
-
name: field.name,
|
|
285
|
-
dataType: this.fieldTypeToGeoPackageType(field.type)
|
|
300
|
+
name: 'formId',
|
|
301
|
+
dataType: 'INTEGER',
|
|
302
|
+
default: form.id
|
|
286
303
|
});
|
|
304
|
+
for (let i = 0; i < form.fields.length; i++) {
|
|
305
|
+
const field = form.fields[i];
|
|
306
|
+
columns.push({
|
|
307
|
+
dataColumn: {
|
|
308
|
+
column_name: field.name,
|
|
309
|
+
table_name: 'Form_' + form.id,
|
|
310
|
+
name: field.title,
|
|
311
|
+
title: field.title
|
|
312
|
+
},
|
|
313
|
+
name: field.name,
|
|
314
|
+
dataType: this.fieldTypeToGeoPackageType(field.type)
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
yield geopackage.createAttributesTableFromProperties('Form_' + form.id, columns);
|
|
287
318
|
}
|
|
288
|
-
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
fieldTypeToGeoPackageType(fieldType) {
|
|
322
|
+
switch (fieldType) {
|
|
323
|
+
case 'numberfield':
|
|
324
|
+
return 'INTEGER';
|
|
325
|
+
case 'attachment':
|
|
326
|
+
case 'textarea':
|
|
327
|
+
case 'textfield':
|
|
328
|
+
return 'TEXT';
|
|
329
|
+
default:
|
|
330
|
+
return 'TEXT';
|
|
289
331
|
}
|
|
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
332
|
}
|
|
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'
|
|
333
|
+
createUserTable(geopackage) {
|
|
334
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
335
|
+
const columns = [];
|
|
336
|
+
columns.push({
|
|
337
|
+
name: 'username',
|
|
338
|
+
dataType: 'TEXT'
|
|
339
|
+
});
|
|
340
|
+
columns.push({
|
|
341
|
+
name: 'displayName',
|
|
342
|
+
dataType: 'TEXT'
|
|
343
|
+
});
|
|
344
|
+
columns.push({
|
|
345
|
+
name: 'email',
|
|
346
|
+
dataType: 'TEXT'
|
|
347
|
+
});
|
|
348
|
+
columns.push({
|
|
349
|
+
name: 'phones',
|
|
350
|
+
dataType: 'TEXT'
|
|
351
|
+
});
|
|
352
|
+
columns.push({
|
|
353
|
+
name: 'userId',
|
|
354
|
+
dataType: 'TEXT'
|
|
355
|
+
});
|
|
356
|
+
columns.push({
|
|
357
|
+
name: 'timestamp',
|
|
358
|
+
dataType: 'DATETIME'
|
|
359
|
+
});
|
|
360
|
+
yield geopackage.createFeatureTableFromProperties('Users', columns);
|
|
361
|
+
log.info('create user avatar table');
|
|
362
|
+
yield geopackage.createMediaTable('UserAvatars', void (0) /* really is optional */);
|
|
360
363
|
});
|
|
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();
|
|
364
|
+
}
|
|
365
|
+
addFormDataToGeoPackage(geopackage) {
|
|
366
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
367
|
+
const columns = [];
|
|
368
|
+
columns.push({
|
|
369
|
+
name: 'formName',
|
|
370
|
+
dataType: 'TEXT'
|
|
371
|
+
});
|
|
372
|
+
columns.push({
|
|
373
|
+
name: 'primaryField',
|
|
374
|
+
dataType: 'TEXT'
|
|
375
|
+
});
|
|
376
|
+
columns.push({
|
|
377
|
+
name: 'variantField',
|
|
378
|
+
dataType: 'TEXT'
|
|
379
|
+
});
|
|
380
|
+
columns.push({
|
|
381
|
+
name: 'color',
|
|
382
|
+
dataType: 'TEXT'
|
|
383
|
+
});
|
|
384
|
+
columns.push({
|
|
385
|
+
name: 'formId',
|
|
386
|
+
dataType: 'TEXT'
|
|
387
|
+
});
|
|
388
|
+
yield geopackage.createAttributesTableFromProperties('Forms', columns);
|
|
389
|
+
for (const form of this._event.forms) {
|
|
390
|
+
const row = {
|
|
391
|
+
formName: form.name,
|
|
392
|
+
primaryField: form.primaryField || null,
|
|
393
|
+
variantField: form.variantField || null,
|
|
394
|
+
color: form.color,
|
|
395
|
+
formId: form.id
|
|
396
|
+
};
|
|
397
|
+
geopackage.addAttributeRow('Forms', row);
|
|
406
398
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
addObservationsToGeoPackage(geopackage) {
|
|
402
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
403
|
+
log.info('requesting locations from db');
|
|
404
|
+
this.createAttachmentTable(geopackage);
|
|
405
|
+
const cursor = this.requestObservations(this._filter);
|
|
406
|
+
let numObservations = 0;
|
|
407
|
+
let zoomToEnvelope;
|
|
408
|
+
return cursor.eachAsync((observation) => __awaiter(this, void 0, void 0, function* () {
|
|
409
|
+
console.debug('exporting observation', observation.id, '...');
|
|
410
|
+
numObservations++;
|
|
411
|
+
if (!Array.isArray(observation.properties.forms)) {
|
|
412
|
+
return;
|
|
419
413
|
}
|
|
420
|
-
|
|
421
|
-
|
|
414
|
+
const primaryEntry = observation.properties.forms[0];
|
|
415
|
+
if (!primaryEntry) {
|
|
416
|
+
return;
|
|
422
417
|
}
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
418
|
+
const form = this._event.formFor(primaryEntry.formId);
|
|
419
|
+
const primary = (form === null || form === void 0 ? void 0 : form.primaryField) ? String(primaryEntry[form.primaryField]) : null;
|
|
420
|
+
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;
|
|
421
|
+
const properties = {
|
|
422
|
+
lastModified: observation.lastModified,
|
|
423
|
+
timestamp: observation.properties.timestamp,
|
|
424
|
+
mageId: observation._id.toString(),
|
|
425
|
+
createdAt: observation.createdAt,
|
|
426
|
+
primaryField: primary,
|
|
427
|
+
variantField: variant
|
|
428
|
+
};
|
|
429
|
+
if (observation.userId) {
|
|
430
|
+
properties.userId = observation.userId.toString();
|
|
431
|
+
}
|
|
432
|
+
if (observation.deviceId) {
|
|
433
|
+
properties.deviceId = observation.deviceId.toString();
|
|
434
|
+
}
|
|
435
|
+
const feature = {
|
|
436
|
+
type: 'Feature',
|
|
437
|
+
geometry: observation.geometry,
|
|
438
|
+
properties
|
|
439
|
+
};
|
|
440
|
+
zoomToEnvelope = calculateBounds(feature.geometry, zoomToEnvelope);
|
|
441
|
+
const featureId = geopackage.addGeoJSONFeatureToGeoPackage(feature, 'Observations');
|
|
442
|
+
const iconSpec = {
|
|
443
|
+
eventId: this._event.id,
|
|
444
|
+
formId: primaryEntry.formId,
|
|
445
|
+
primary,
|
|
446
|
+
variant,
|
|
447
|
+
};
|
|
448
|
+
yield this.linkObservationFeatureIcon(iconSpec, featureId);
|
|
449
|
+
const formEntries = observation.properties.forms || [];
|
|
450
|
+
for (const formEntry of formEntries) {
|
|
451
|
+
const form = this._event.formFor(formEntry.formId);
|
|
452
|
+
const primary = form.primaryField ? String(formEntry[form.primaryField]) : null;
|
|
453
|
+
const variant = form.primaryField && form.variantField ? String(formEntry[form.variantField]) : null;
|
|
432
454
|
const formToSave = {
|
|
433
455
|
primaryField: primary,
|
|
434
456
|
variantField: variant,
|
|
435
|
-
formId:
|
|
457
|
+
formId: formEntry.formId
|
|
436
458
|
};
|
|
437
459
|
const attachments = [];
|
|
438
460
|
if (observation.attachments) {
|
|
439
461
|
observation.attachments.forEach((attachment) => {
|
|
440
|
-
if (attachment.observationFormId
|
|
462
|
+
if (String(attachment.observationFormId) === String(formEntry._id)) {
|
|
441
463
|
attachments.push(attachment);
|
|
442
|
-
|
|
443
|
-
|
|
464
|
+
const attachmentFieldEntries = (formEntry[attachment.fieldName] || []);
|
|
465
|
+
attachmentFieldEntries.push(String(attachment._id));
|
|
466
|
+
formEntry[attachment.fieldName] = attachmentFieldEntries;
|
|
444
467
|
}
|
|
445
468
|
});
|
|
446
469
|
}
|
|
447
|
-
Object.keys(
|
|
448
|
-
|
|
470
|
+
Object.keys(formEntry).forEach(key => {
|
|
471
|
+
const fieldEntry = formEntry[key];
|
|
472
|
+
if (fieldEntry === null || fieldEntry === undefined) {
|
|
449
473
|
return;
|
|
450
|
-
|
|
451
|
-
|
|
474
|
+
}
|
|
475
|
+
const field = this._event.formFieldFor(key, form.id);
|
|
476
|
+
if (!field) {
|
|
452
477
|
return;
|
|
453
|
-
if (fieldDefinition.type === 'multiselectdropdown') {
|
|
454
|
-
formToSave[key] = observationForm[key].join(', ');
|
|
455
478
|
}
|
|
456
|
-
|
|
457
|
-
formToSave[key] =
|
|
479
|
+
if (field.type === 'multiselectdropdown') {
|
|
480
|
+
formToSave[key] = fieldEntry.join(', ');
|
|
458
481
|
}
|
|
459
|
-
else if (
|
|
460
|
-
formToSave[key] =
|
|
482
|
+
else if (field.type === 'date') {
|
|
483
|
+
formToSave[key] = (0, moment_1.default)(fieldEntry).toISOString();
|
|
461
484
|
}
|
|
462
|
-
else if (
|
|
463
|
-
formToSave[key] =
|
|
485
|
+
else if (field.type === 'checkbox') {
|
|
486
|
+
formToSave[key] = String(fieldEntry);
|
|
464
487
|
}
|
|
465
|
-
else if (
|
|
466
|
-
formToSave[key] =
|
|
488
|
+
else if (field.type === 'geometry') {
|
|
489
|
+
formToSave[key] = wkx_1.default.Geometry.parseGeoJSON(fieldEntry).toWkt();
|
|
490
|
+
}
|
|
491
|
+
else if (field.type === 'attachment') {
|
|
492
|
+
formToSave[key] = fieldEntry.join(', ');
|
|
467
493
|
}
|
|
468
494
|
else {
|
|
469
|
-
formToSave[key] =
|
|
495
|
+
formToSave[key] = fieldEntry;
|
|
470
496
|
}
|
|
471
497
|
});
|
|
472
498
|
try {
|
|
473
499
|
const rowId = geopackage.addAttributeRow('Form_' + formToSave.formId, formToSave);
|
|
474
500
|
if (attachments.length) {
|
|
475
|
-
yield
|
|
501
|
+
yield addAttachments(geopackage, attachments, featureId, 'Form_' + formToSave.formId, rowId);
|
|
476
502
|
}
|
|
477
|
-
yield geopackage.linkRelatedRows('Observations', featureId, 'Form_' + formToSave.formId, rowId, RelationType.ATTRIBUTES);
|
|
503
|
+
yield geopackage.linkRelatedRows('Observations', featureId, 'Form_' + formToSave.formId, rowId, relationType_1.RelationType.ATTRIBUTES);
|
|
478
504
|
}
|
|
479
505
|
catch (e) {
|
|
480
|
-
|
|
506
|
+
log.error(`error writing rows for form entry ${formEntry.id} of observation ${observation.id} to geopackage`, e);
|
|
481
507
|
}
|
|
482
508
|
}
|
|
509
|
+
}))
|
|
510
|
+
.then(() => __awaiter(this, void 0, void 0, function* () {
|
|
511
|
+
if (cursor) {
|
|
512
|
+
yield cursor.close();
|
|
513
|
+
}
|
|
514
|
+
const featureDao = geopackage.getFeatureDao('Observations');
|
|
515
|
+
const rtreeIndex = new GPKG.RTreeIndex(geopackage, featureDao);
|
|
516
|
+
rtreeIndex.create();
|
|
517
|
+
if (zoomToEnvelope) {
|
|
518
|
+
setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
519
|
+
}
|
|
520
|
+
log.info(`'wrote ${numObservations} observations to geopackage`);
|
|
521
|
+
}))
|
|
522
|
+
.catch(err => {
|
|
523
|
+
log.warn(err);
|
|
524
|
+
});
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
createObservationFeatureTableStyles(geopackage) {
|
|
528
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
529
|
+
const featureTableName = 'Observations';
|
|
530
|
+
const featureTableStyles = new GPKG.FeatureTableStyles(geopackage, featureTableName);
|
|
531
|
+
yield geopackage.featureStyleExtension.getOrCreateExtension(featureTableName);
|
|
532
|
+
yield geopackage.featureStyleExtension.getRelatedTables().getOrCreateExtension();
|
|
533
|
+
yield geopackage.featureStyleExtension.getContentsId().getOrCreateExtension();
|
|
534
|
+
featureTableStyles.createRelationships();
|
|
535
|
+
const defaultIconAccess = new api_1.default.Icon(this._event.id);
|
|
536
|
+
const defaultIconDoc = yield util_1.default.promisify(defaultIconAccess.getIcon.bind(defaultIconAccess))();
|
|
537
|
+
if (!defaultIconDoc || isNothing(defaultIconDoc.path)) {
|
|
538
|
+
return featureTableStyles;
|
|
483
539
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
this.setContentBounds(geopackage, featureDao, zoomToEnvelope);
|
|
540
|
+
try {
|
|
541
|
+
const iconBytes = yield promises_1.default.readFile(defaultIconDoc.path);
|
|
542
|
+
const gpkgIconRow = featureTableStyles.getIconDao().newRow();
|
|
543
|
+
gpkgIconRow.data = iconBytes;
|
|
544
|
+
populateGpkgIconRow(gpkgIconRow, defaultIconDoc, this._event);
|
|
545
|
+
featureTableStyles.setTableIconDefault(gpkgIconRow);
|
|
546
|
+
this.iconCache.put(defaultIconDoc, gpkgIconRow.id);
|
|
492
547
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
548
|
+
catch (err) {
|
|
549
|
+
console.warn('error setting default icon', defaultIconDoc.path);
|
|
550
|
+
}
|
|
551
|
+
return featureTableStyles;
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
linkObservationFeatureIcon(iconSpec, featureId) {
|
|
555
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
556
|
+
const iconId = yield this.ensureIconInGeopackage(iconSpec);
|
|
557
|
+
if (iconId === null) {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
const styleExt = this.observationStyles.getFeatureStyleExtension();
|
|
561
|
+
const iconMappingDao = this.observationStyles.getIconMappingDao();
|
|
562
|
+
styleExt.insertStyleMapping(iconMappingDao, featureId, iconId);
|
|
563
|
+
});
|
|
503
564
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
565
|
+
ensureIconInGeopackage(iconSpec) {
|
|
566
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
567
|
+
const cachedIconId = this.iconCache.get(iconSpec);
|
|
568
|
+
if (cachedIconId === IconTreeCache.ICON_LOAD_ERROR) {
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
if (cachedIconId !== null) {
|
|
572
|
+
return cachedIconId;
|
|
573
|
+
}
|
|
574
|
+
const iconAccess = new api_1.default.Icon(this._event.id, iconSpec.formId, iconSpec.primary, iconSpec.variant);
|
|
575
|
+
const iconDoc = yield util_1.default.promisify(iconAccess.getIcon.bind(iconAccess))();
|
|
576
|
+
if (!iconDoc || isNothing(iconDoc.path)) {
|
|
577
|
+
return null;
|
|
578
|
+
}
|
|
579
|
+
try {
|
|
580
|
+
const iconBytes = yield promises_1.default.readFile(iconDoc.path);
|
|
581
|
+
const gpkgIconRow = this.observationStyles.getIconDao().newRow();
|
|
582
|
+
gpkgIconRow.data = iconBytes;
|
|
583
|
+
populateGpkgIconRow(gpkgIconRow, iconDoc, this._event);
|
|
584
|
+
const id = this.observationStyles.getIconDao().create(gpkgIconRow);
|
|
585
|
+
this.iconCache.put(iconDoc, id);
|
|
586
|
+
return id;
|
|
587
|
+
}
|
|
588
|
+
catch (err) {
|
|
589
|
+
console.warn('error adding icon', iconDoc.path, err);
|
|
590
|
+
}
|
|
591
|
+
this.iconCache.put(iconDoc, IconTreeCache.ICON_LOAD_ERROR);
|
|
592
|
+
return null;
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
exports.GeoPackage = GeoPackage;
|
|
597
|
+
function populateGpkgIconRow(gpkgIconRow, iconDoc, mageEvent) {
|
|
598
|
+
gpkgIconRow.contentType = 'image/png';
|
|
599
|
+
gpkgIconRow.width = 20;
|
|
600
|
+
gpkgIconRow.anchorU = 0.5;
|
|
601
|
+
gpkgIconRow.anchorV = 1.0;
|
|
602
|
+
const defaultName = `${mageEvent.name} default`;
|
|
603
|
+
const name = (() => {
|
|
604
|
+
if (isNothing(iconDoc.formId)) {
|
|
605
|
+
if (isNothing(iconDoc.primary)) {
|
|
606
|
+
if (isNothing(iconDoc.variant)) {
|
|
607
|
+
return defaultName;
|
|
608
|
+
}
|
|
609
|
+
return iconDoc.variant;
|
|
610
|
+
}
|
|
611
|
+
return iconDoc.primary;
|
|
507
612
|
}
|
|
508
|
-
|
|
509
|
-
|
|
613
|
+
const form = mageEvent.formFor(iconDoc.formId);
|
|
614
|
+
if (!form) {
|
|
615
|
+
return defaultName;
|
|
510
616
|
}
|
|
511
|
-
|
|
512
|
-
|
|
617
|
+
return `${form.name} icon`;
|
|
618
|
+
})();
|
|
619
|
+
gpkgIconRow.name = name;
|
|
620
|
+
return gpkgIconRow;
|
|
621
|
+
}
|
|
622
|
+
function isNothing(wut) {
|
|
623
|
+
return wut === null || wut === undefined || wut === '' || (typeof wut === 'number' && isNaN(wut));
|
|
624
|
+
}
|
|
625
|
+
class IconTreeCache {
|
|
626
|
+
constructor() {
|
|
627
|
+
this.root = new IconTreeCacheNode();
|
|
628
|
+
}
|
|
629
|
+
get(icon) {
|
|
630
|
+
const { formId, primary, variant } = icon;
|
|
631
|
+
if (!isNothing(formId)) {
|
|
632
|
+
const formNode = this.root.children[formId];
|
|
633
|
+
if (formNode) {
|
|
634
|
+
if (!isNothing(primary)) {
|
|
635
|
+
const primaryNode = formNode.children[primary];
|
|
636
|
+
if (primaryNode) {
|
|
637
|
+
if (!isNothing(variant)) {
|
|
638
|
+
const variantNode = primaryNode.children[variant];
|
|
639
|
+
return (variantNode === null || variantNode === void 0 ? void 0 : variantNode.gpkgIconId) || null;
|
|
640
|
+
}
|
|
641
|
+
return primaryNode.gpkgIconId;
|
|
642
|
+
}
|
|
643
|
+
return null;
|
|
644
|
+
}
|
|
645
|
+
return formNode.gpkgIconId;
|
|
646
|
+
}
|
|
647
|
+
return null;
|
|
513
648
|
}
|
|
514
|
-
|
|
515
|
-
|
|
649
|
+
return this.root.gpkgIconId;
|
|
650
|
+
}
|
|
651
|
+
put(icon, gpkgIconId) {
|
|
652
|
+
const node = this.ensurePathNodes(icon);
|
|
653
|
+
node.gpkgIconId = gpkgIconId;
|
|
654
|
+
return this;
|
|
655
|
+
}
|
|
656
|
+
ensurePathNodes(path) {
|
|
657
|
+
const { formId, primary, variant } = path;
|
|
658
|
+
if (!isNothing(formId)) {
|
|
659
|
+
const formNode = this.root.children[formId] = this.root.children[formId] || new IconTreeCacheNode();
|
|
660
|
+
if (!isNothing(primary)) {
|
|
661
|
+
const primaryNode = formNode.children[primary] = formNode.children[primary] || new IconTreeCacheNode();
|
|
662
|
+
if (!isNothing(variant)) {
|
|
663
|
+
return primaryNode.children[variant] = primaryNode.children[variant] || new IconTreeCacheNode();
|
|
664
|
+
}
|
|
665
|
+
return primaryNode;
|
|
666
|
+
}
|
|
667
|
+
return formNode;
|
|
516
668
|
}
|
|
669
|
+
return this.root;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
IconTreeCache.ICON_LOAD_ERROR = Number.MIN_SAFE_INTEGER;
|
|
673
|
+
class IconTreeCacheNode {
|
|
674
|
+
constructor(gpkgRowId = null, children = {}) {
|
|
675
|
+
this.gpkgIconId = null;
|
|
676
|
+
this.gpkgIconId = isNothing(gpkgRowId) ? null : gpkgRowId;
|
|
677
|
+
this.children = children;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
function createGeoPackageFile() {
|
|
681
|
+
const filename = (0, moment_1.default)().format('YYYMMDD_hhmmssSSS') + '.gpkg';
|
|
682
|
+
const filePath = path_1.default.join(os_1.default.tmpdir(), filename);
|
|
683
|
+
return new Promise(function (resolve, reject) {
|
|
684
|
+
fs_1.default.unlink(filePath, function () {
|
|
685
|
+
fs_1.default.mkdir(path_1.default.dirname(filePath), function () {
|
|
686
|
+
fs_1.default.open(filePath, 'w', function (err) {
|
|
687
|
+
if (err)
|
|
688
|
+
return reject(err);
|
|
689
|
+
resolve(filePath);
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
function calculateBounds(geometry, zoomToEnvelope) {
|
|
696
|
+
const wkxGeometry = wkx_1.default.Geometry.parseGeoJSON(geometry);
|
|
697
|
+
const envelope = envelopeBuilder_1.EnvelopeBuilder.buildEnvelopeWithGeometry(wkxGeometry);
|
|
698
|
+
if (!zoomToEnvelope) {
|
|
699
|
+
return envelope;
|
|
700
|
+
}
|
|
701
|
+
if (zoomToEnvelope.maxX < envelope.maxX) {
|
|
702
|
+
zoomToEnvelope.maxX = envelope.maxX;
|
|
703
|
+
}
|
|
704
|
+
if (zoomToEnvelope.maxY < envelope.maxY) {
|
|
705
|
+
zoomToEnvelope.maxY = envelope.maxY;
|
|
706
|
+
}
|
|
707
|
+
if (zoomToEnvelope.minX > envelope.minX) {
|
|
708
|
+
zoomToEnvelope.minX = envelope.minX;
|
|
709
|
+
}
|
|
710
|
+
if (zoomToEnvelope.minY > envelope.minY) {
|
|
711
|
+
zoomToEnvelope.minY = envelope.minY;
|
|
517
712
|
}
|
|
518
713
|
return zoomToEnvelope;
|
|
519
|
-
}
|
|
520
|
-
|
|
714
|
+
}
|
|
715
|
+
function addAttachments(geopackage, attachments, observationId, formTable, formRowId) {
|
|
521
716
|
return __awaiter(this, void 0, void 0, function* () {
|
|
522
|
-
log.info('
|
|
717
|
+
log.info('add attachments');
|
|
523
718
|
for (let i = 0; i < attachments.length; i++) {
|
|
524
719
|
const attachment = attachments[i];
|
|
525
720
|
if (attachment.relativePath) {
|
|
526
721
|
yield new Promise(function (resolve, reject) {
|
|
527
|
-
|
|
528
|
-
if (err)
|
|
722
|
+
fs_1.default.readFile(path_1.default.join(attachmentBase, attachment.relativePath), (err, dataBuffer) => __awaiter(this, void 0, void 0, function* () {
|
|
723
|
+
if (err) {
|
|
529
724
|
return reject(err);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
725
|
+
}
|
|
726
|
+
const mediaId = geopackage.addMedia('Attachments', dataBuffer, attachment.contentType || 'application/octet-stream', {
|
|
727
|
+
name: attachment.name || attachment._id,
|
|
728
|
+
size: attachment.size || 0
|
|
533
729
|
});
|
|
534
730
|
yield geopackage.linkMedia('Observations', observationId, 'Attachments', mediaId);
|
|
535
731
|
resolve(geopackage.linkMedia(formTable, formRowId, 'Attachments', mediaId));
|
|
@@ -538,144 +734,18 @@ GeoPackage.prototype.addAttachments = function (geopackage, attachments, observa
|
|
|
538
734
|
}
|
|
539
735
|
}
|
|
540
736
|
});
|
|
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) {
|
|
737
|
+
}
|
|
738
|
+
function createUserFeatureTableStyles(geopackage) {
|
|
555
739
|
return __awaiter(this, void 0, void 0, function* () {
|
|
556
740
|
const featureTableName = 'Users';
|
|
557
|
-
const featureTableStyles = new
|
|
741
|
+
const featureTableStyles = new GPKG.FeatureTableStyles(geopackage, featureTableName);
|
|
558
742
|
yield geopackage.featureStyleExtension.getOrCreateExtension(featureTableName);
|
|
559
743
|
yield geopackage.featureStyleExtension.getRelatedTables().getOrCreateExtension();
|
|
560
744
|
yield geopackage.featureStyleExtension.getContentsId().getOrCreateExtension();
|
|
561
745
|
featureTableStyles.createRelationships();
|
|
562
|
-
return geopackage;
|
|
563
746
|
});
|
|
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) {
|
|
747
|
+
}
|
|
748
|
+
function setContentBounds(geopackage, featureDao, zoomToEnvelope) {
|
|
679
749
|
const contents = featureDao.getContents();
|
|
680
750
|
contents.max_x = zoomToEnvelope.maxX;
|
|
681
751
|
contents.max_y = zoomToEnvelope.maxY;
|
|
@@ -683,5 +753,5 @@ GeoPackage.prototype.setContentBounds = function (geopackage, featureDao, zoomTo
|
|
|
683
753
|
contents.min_y = zoomToEnvelope.minY;
|
|
684
754
|
const contentsDao = geopackage.contentsDao;
|
|
685
755
|
contentsDao.update(contents);
|
|
686
|
-
}
|
|
756
|
+
}
|
|
687
757
|
//# sourceMappingURL=geopackage.js.map
|