Fix CSP issues
This commit is contained in:
parent
56b83cfa36
commit
06c2e2fec8
7 changed files with 227 additions and 147 deletions
|
@ -279,6 +279,7 @@ async function generateCsp(
|
||||||
"https://www.openstreetmap.org",
|
"https://www.openstreetmap.org",
|
||||||
"https://api.openstreetmap.org",
|
"https://api.openstreetmap.org",
|
||||||
"https://pietervdvn.goatcounter.com",
|
"https://pietervdvn.goatcounter.com",
|
||||||
|
"https://cache.mapcomplete.org",
|
||||||
].concat(...(await eliUrls()))
|
].concat(...(await eliUrls()))
|
||||||
|
|
||||||
SpecialVisualizations.specialVisualizations.forEach((sv) => {
|
SpecialVisualizations.specialVisualizations.forEach((sv) => {
|
||||||
|
@ -289,7 +290,13 @@ async function generateCsp(
|
||||||
apiUrls.push(...(sv.needsUrls ?? []))
|
apiUrls.push(...(sv.needsUrls ?? []))
|
||||||
})
|
})
|
||||||
|
|
||||||
const usedSpecialVisualisations = [].concat(...layoutJson.layers.map(l => ValidationUtils.getAllSpecialVisualisations(<QuestionableTagRenderingConfigJson[]> (<LayerConfigJson>l).tagRenderings ?? [])))
|
const usedSpecialVisualisations = [].concat(
|
||||||
|
...layoutJson.layers.map((l) =>
|
||||||
|
ValidationUtils.getAllSpecialVisualisations(
|
||||||
|
<QuestionableTagRenderingConfigJson[]>(<LayerConfigJson>l).tagRenderings ?? []
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
for (const usedSpecialVisualisation of usedSpecialVisualisations) {
|
for (const usedSpecialVisualisation of usedSpecialVisualisations) {
|
||||||
if (typeof usedSpecialVisualisation === "string") {
|
if (typeof usedSpecialVisualisation === "string") {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -16,9 +16,9 @@ npm run test &&
|
||||||
npm run prepare-deploy &&
|
npm run prepare-deploy &&
|
||||||
zip dist.zip -r dist/* &&
|
zip dist.zip -r dist/* &&
|
||||||
mv config.json.bu config.json &&
|
mv config.json.bu config.json &&
|
||||||
scp ./scripts/hetzner/config/* hetzner:/root/ &&
|
scp ./Docs/ServerConfig/hetzner/* hetzner:/root/ &&
|
||||||
rsync -rzh --progress dist.zip hetzner:/root/ &&
|
rsync -rzh --progress dist.zip hetzner:/root/ &&
|
||||||
echo "Upload completed, deploying config and booting" &&
|
echo "Upload completed, deploying config and booting" &&
|
||||||
ssh hetzner -t "unzip dist.zip && rm dist.zip && rm -rf public/ && mv dist public && caddy stop && caddy start" &&
|
ssh hetzner -t "unzip dist.zip && rm dist.zip && rm -rf public/ && mv dist public && caddy stop && caddy start" &&
|
||||||
rm dist.zip
|
# rm dist.zip
|
||||||
npm run clean
|
npm run clean
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Feature, Geometry } from "geojson"
|
import { Geometry } from "geojson"
|
||||||
|
import { Feature as GeojsonFeature } from "geojson"
|
||||||
|
|
||||||
import { Store, UIEventSource } from "../../UIEventSource"
|
import { Store, UIEventSource } from "../../UIEventSource"
|
||||||
import { FeatureSourceForTile } from "../FeatureSource"
|
import { FeatureSourceForTile } from "../FeatureSource"
|
||||||
import Pbf from "pbf"
|
import Pbf from "pbf"
|
||||||
import * as pbfCompile from "pbf/compile"
|
|
||||||
import * as PbfSchema from "protocol-buffers-schema"
|
|
||||||
|
|
||||||
type Coords = [number, number][]
|
type Coords = [number, number][]
|
||||||
|
|
||||||
|
@ -60,12 +60,11 @@ class MvtFeatureBuilder {
|
||||||
}
|
}
|
||||||
const ccw = area < 0
|
const ccw = area < 0
|
||||||
|
|
||||||
if (ccw === (area < 0)) {
|
if (ccw === area < 0) {
|
||||||
if (currentPolygon) {
|
if (currentPolygon) {
|
||||||
polygons.push(currentPolygon)
|
polygons.push(currentPolygon)
|
||||||
}
|
}
|
||||||
currentPolygon = [ring]
|
currentPolygon = [ring]
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
currentPolygon.push(ring)
|
currentPolygon.push(ring)
|
||||||
}
|
}
|
||||||
|
@ -77,7 +76,7 @@ class MvtFeatureBuilder {
|
||||||
return polygons
|
return polygons
|
||||||
}
|
}
|
||||||
|
|
||||||
public toGeoJson(geometry: number[], typeIndex: 1 | 2 | 3, properties: any): Feature {
|
public toGeoJson(geometry: number[], typeIndex: 1 | 2 | 3, properties: any): GeojsonFeature {
|
||||||
let coords: Coords[] = this.encodeGeometry(geometry)
|
let coords: Coords[] = this.encodeGeometry(geometry)
|
||||||
let classified = undefined
|
let classified = undefined
|
||||||
switch (typeIndex) {
|
switch (typeIndex) {
|
||||||
|
@ -159,9 +158,9 @@ class MvtFeatureBuilder {
|
||||||
if (commandId === 1 || commandId === 2) {
|
if (commandId === 1 || commandId === 2) {
|
||||||
for (let j = 0; j < commandCount; j++) {
|
for (let j = 0; j < commandCount; j++) {
|
||||||
const dx = geometry[i + j * 2 + 1]
|
const dx = geometry[i + j * 2 + 1]
|
||||||
cX += ((dx >> 1) ^ (-(dx & 1)))
|
cX += (dx >> 1) ^ -(dx & 1)
|
||||||
const dy = geometry[i + j * 2 + 2]
|
const dy = geometry[i + j * 2 + 2]
|
||||||
cY += ((dy >> 1) ^ (-(dy & 1)))
|
cY += (dy >> 1) ^ -(dy & 1)
|
||||||
currentRing.push([cX, cY])
|
currentRing.push([cX, cY])
|
||||||
}
|
}
|
||||||
i += commandCount * 2
|
i += commandCount * 2
|
||||||
|
@ -170,7 +169,6 @@ class MvtFeatureBuilder {
|
||||||
currentRing.push([...currentRing[0]])
|
currentRing.push([...currentRing[0]])
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (currentRing.length > 0) {
|
if (currentRing.length > 0) {
|
||||||
coordss.push(currentRing)
|
coordss.push(currentRing)
|
||||||
|
@ -189,132 +187,182 @@ class MvtFeatureBuilder {
|
||||||
const size = this._size
|
const size = this._size
|
||||||
for (let i = 0; i < line.length; i++) {
|
for (let i = 0; i < line.length; i++) {
|
||||||
let p = line[i]
|
let p = line[i]
|
||||||
let y2 = 180 - (p[1] + y0) * 360 / size
|
let y2 = 180 - ((p[1] + y0) * 360) / size
|
||||||
line[i] = [
|
line[i] = [
|
||||||
(p[0] + x0) * 360 / size - 180,
|
((p[0] + x0) * 360) / size - 180,
|
||||||
360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90,
|
(360 / Math.PI) * Math.atan(Math.exp((y2 * Math.PI) / 180)) - 90,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Layer {
|
||||||
|
public static read(pbf, end) {
|
||||||
|
return pbf.readFields(
|
||||||
|
Layer._readField,
|
||||||
|
{ version: 0, name: "", features: [], keys: [], values: [], extent: 0 },
|
||||||
|
end
|
||||||
|
)
|
||||||
|
}
|
||||||
|
static _readField(tag, obj, pbf) {
|
||||||
|
if (tag === 15) obj.version = pbf.readVarint()
|
||||||
|
else if (tag === 1) obj.name = pbf.readString()
|
||||||
|
else if (tag === 2) obj.features.push(Feature.read(pbf, pbf.readVarint() + pbf.pos))
|
||||||
|
else if (tag === 3) obj.keys.push(pbf.readString())
|
||||||
|
else if (tag === 4) obj.values.push(Value.read(pbf, pbf.readVarint() + pbf.pos))
|
||||||
|
else if (tag === 5) obj.extent = pbf.readVarint()
|
||||||
|
}
|
||||||
|
public static write(obj, pbf) {
|
||||||
|
if (obj.version) pbf.writeVarintField(15, obj.version)
|
||||||
|
if (obj.name) pbf.writeStringField(1, obj.name)
|
||||||
|
if (obj.features)
|
||||||
|
for (var i = 0; i < obj.features.length; i++)
|
||||||
|
pbf.writeMessage(2, Feature.write, obj.features[i])
|
||||||
|
if (obj.keys) for (i = 0; i < obj.keys.length; i++) pbf.writeStringField(3, obj.keys[i])
|
||||||
|
if (obj.values)
|
||||||
|
for (i = 0; i < obj.values.length; i++) pbf.writeMessage(4, Value.write, obj.values[i])
|
||||||
|
if (obj.extent) pbf.writeVarintField(5, obj.extent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Feature {
|
||||||
|
static read(pbf, end) {
|
||||||
|
return pbf.readFields(Feature._readField, { id: 0, tags: [], type: 0, geometry: [] }, end)
|
||||||
|
}
|
||||||
|
static _readField(tag, obj, pbf) {
|
||||||
|
if (tag === 1) obj.id = pbf.readVarint()
|
||||||
|
else if (tag === 2) pbf.readPackedVarint(obj.tags)
|
||||||
|
else if (tag === 3) obj.type = pbf.readVarint()
|
||||||
|
else if (tag === 4) pbf.readPackedVarint(obj.geometry)
|
||||||
|
}
|
||||||
|
public static write(obj, pbf) {
|
||||||
|
if (obj.id) pbf.writeVarintField(1, obj.id)
|
||||||
|
if (obj.tags) pbf.writePackedVarint(2, obj.tags)
|
||||||
|
if (obj.type) pbf.writeVarintField(3, obj.type)
|
||||||
|
if (obj.geometry) pbf.writePackedVarint(4, obj.geometry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Value {
|
||||||
|
public static read(pbf, end) {
|
||||||
|
return pbf.readFields(
|
||||||
|
Value._readField,
|
||||||
|
{
|
||||||
|
string_value: "",
|
||||||
|
float_value: 0,
|
||||||
|
double_value: 0,
|
||||||
|
int_value: 0,
|
||||||
|
uint_value: 0,
|
||||||
|
sint_value: 0,
|
||||||
|
bool_value: false,
|
||||||
|
},
|
||||||
|
end
|
||||||
|
)
|
||||||
|
}
|
||||||
|
static _readField = function (tag, obj, pbf) {
|
||||||
|
if (tag === 1) obj.string_value = pbf.readString()
|
||||||
|
else if (tag === 2) obj.float_value = pbf.readFloat()
|
||||||
|
else if (tag === 3) obj.double_value = pbf.readDouble()
|
||||||
|
else if (tag === 4) obj.int_value = pbf.readVarint(true)
|
||||||
|
else if (tag === 5) obj.uint_value = pbf.readVarint()
|
||||||
|
else if (tag === 6) obj.sint_value = pbf.readSVarint()
|
||||||
|
else if (tag === 7) obj.bool_value = pbf.readBoolean()
|
||||||
|
}
|
||||||
|
public static write(obj, pbf) {
|
||||||
|
if (obj.string_value) pbf.writeStringField(1, obj.string_value)
|
||||||
|
if (obj.float_value) pbf.writeFloatField(2, obj.float_value)
|
||||||
|
if (obj.double_value) pbf.writeDoubleField(3, obj.double_value)
|
||||||
|
if (obj.int_value) pbf.writeVarintField(4, obj.int_value)
|
||||||
|
if (obj.uint_value) pbf.writeVarintField(5, obj.uint_value)
|
||||||
|
if (obj.sint_value) pbf.writeSVarintField(6, obj.sint_value)
|
||||||
|
if (obj.bool_value) pbf.writeBooleanField(7, obj.bool_value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Tile {
|
||||||
|
// code generated by pbf v3.2.1
|
||||||
|
|
||||||
|
public static read(pbf, end) {
|
||||||
|
return pbf.readFields(Tile._readField, { layers: [] }, end)
|
||||||
|
}
|
||||||
|
static _readField(tag, obj, pbf) {
|
||||||
|
if (tag === 3) obj.layers.push(Layer.read(pbf, pbf.readVarint() + pbf.pos))
|
||||||
|
}
|
||||||
|
static write(obj, pbf) {
|
||||||
|
if (obj.layers)
|
||||||
|
for (var i = 0; i < obj.layers.length; i++)
|
||||||
|
pbf.writeMessage(3, Layer.write, obj.layers[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
static GeomType = {
|
||||||
|
UNKNOWN: {
|
||||||
|
value: 0,
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
POINT: {
|
||||||
|
value: 1,
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
LINESTRING: {
|
||||||
|
value: 2,
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
POLYGON: {
|
||||||
|
value: 3,
|
||||||
|
options: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class MvtSource implements FeatureSourceForTile {
|
export default class MvtSource implements FeatureSourceForTile {
|
||||||
|
public readonly features: Store<GeojsonFeature<Geometry, { [name: string]: any }>[]>
|
||||||
private static readonly schemaSpec21 = `
|
|
||||||
package vector_tile;
|
|
||||||
|
|
||||||
option optimize_for = LITE_RUNTIME;
|
|
||||||
|
|
||||||
message Tile {
|
|
||||||
|
|
||||||
// GeomType is described in section 4.3.4 of the specification
|
|
||||||
enum GeomType {
|
|
||||||
UNKNOWN = 0;
|
|
||||||
POINT = 1;
|
|
||||||
LINESTRING = 2;
|
|
||||||
POLYGON = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Variant type encoding
|
|
||||||
// The use of values is described in section 4.1 of the specification
|
|
||||||
message Value {
|
|
||||||
// Exactly one of these values must be present in a valid message
|
|
||||||
optional string string_value = 1;
|
|
||||||
optional float float_value = 2;
|
|
||||||
optional double double_value = 3;
|
|
||||||
optional int64 int_value = 4;
|
|
||||||
optional uint64 uint_value = 5;
|
|
||||||
optional sint64 sint_value = 6;
|
|
||||||
optional bool bool_value = 7;
|
|
||||||
|
|
||||||
extensions 8 to max;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Features are described in section 4.2 of the specification
|
|
||||||
message Feature {
|
|
||||||
optional uint64 id = 1 [ default = 0 ];
|
|
||||||
|
|
||||||
// Tags of this feature are encoded as repeated pairs of
|
|
||||||
// integers.
|
|
||||||
// A detailed description of tags is located in sections
|
|
||||||
// 4.2 and 4.4 of the specification
|
|
||||||
repeated uint32 tags = 2 [ packed = true ];
|
|
||||||
|
|
||||||
// The type of geometry stored in this feature.
|
|
||||||
optional GeomType type = 3 [ default = UNKNOWN ];
|
|
||||||
|
|
||||||
// Contains a stream of commands and parameters (vertices).
|
|
||||||
// A detailed description on geometry encoding is located in
|
|
||||||
// section 4.3 of the specification.
|
|
||||||
repeated uint32 geometry = 4 [ packed = true ];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Layers are described in section 4.1 of the specification
|
|
||||||
message Layer {
|
|
||||||
// Any compliant implementation must first read the version
|
|
||||||
// number encoded in this message and choose the correct
|
|
||||||
// implementation for this version number before proceeding to
|
|
||||||
// decode other parts of this message.
|
|
||||||
required uint32 version = 15 [ default = 1 ];
|
|
||||||
|
|
||||||
required string name = 1;
|
|
||||||
|
|
||||||
// The actual features in this tile.
|
|
||||||
repeated Feature features = 2;
|
|
||||||
|
|
||||||
// Dictionary encoding for keys
|
|
||||||
repeated string keys = 3;
|
|
||||||
|
|
||||||
// Dictionary encoding for values
|
|
||||||
repeated Value values = 4;
|
|
||||||
|
|
||||||
// Although this is an "optional" field it is required by the specification.
|
|
||||||
// See https://github.com/mapbox/vector-tile-spec/issues/47
|
|
||||||
optional uint32 extent = 5 [ default = 4096 ];
|
|
||||||
|
|
||||||
extensions 16 to max;
|
|
||||||
}
|
|
||||||
|
|
||||||
repeated Layer layers = 3;
|
|
||||||
|
|
||||||
extensions 16 to 8191;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
private static readonly tile_schema = (pbfCompile.default ?? pbfCompile)(PbfSchema.parse(MvtSource.schemaSpec21)).Tile
|
|
||||||
public readonly features: Store<Feature<Geometry, { [name: string]: any }>[]>
|
|
||||||
private readonly _url: string
|
private readonly _url: string
|
||||||
private readonly _layerName: string
|
private readonly _layerName: string
|
||||||
private readonly _features: UIEventSource<Feature<Geometry, {
|
private readonly _features: UIEventSource<
|
||||||
|
GeojsonFeature<
|
||||||
|
Geometry,
|
||||||
|
{
|
||||||
[name: string]: any
|
[name: string]: any
|
||||||
}>[]> = new UIEventSource<Feature<Geometry, { [p: string]: any }>[]>([])
|
}
|
||||||
|
>[]
|
||||||
|
> = new UIEventSource<GeojsonFeature<Geometry, { [p: string]: any }>[]>([])
|
||||||
public readonly x: number
|
public readonly x: number
|
||||||
public readonly y: number
|
public readonly y: number
|
||||||
public readonly z: number
|
public readonly z: number
|
||||||
|
|
||||||
constructor(url: string, x: number, y: number, z: number, layerName?: string, isActive?: Store<boolean>) {
|
constructor(
|
||||||
|
url: string,
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
layerName?: string,
|
||||||
|
isActive?: Store<boolean>
|
||||||
|
) {
|
||||||
this._url = url
|
this._url = url
|
||||||
this._layerName = layerName
|
this._layerName = layerName
|
||||||
this.x = x
|
this.x = x
|
||||||
this.y = y
|
this.y = y
|
||||||
this.z = z
|
this.z = z
|
||||||
this.downloadSync()
|
this.downloadSync()
|
||||||
this.features = this._features.map(fs => {
|
this.features = this._features.map(
|
||||||
|
(fs) => {
|
||||||
if (fs === undefined || isActive?.data === false) {
|
if (fs === undefined || isActive?.data === false) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
return fs
|
return fs
|
||||||
}, [isActive])
|
},
|
||||||
|
[isActive]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private getValue(v: {
|
private getValue(v: {
|
||||||
// Exactly one of these values must be present in a valid message
|
// Exactly one of these values must be present in a valid message
|
||||||
string_value?: string,
|
string_value?: string
|
||||||
float_value?: number,
|
float_value?: number
|
||||||
double_value?: number,
|
double_value?: number
|
||||||
int_value?: number,
|
int_value?: number
|
||||||
uint_value?: number,
|
uint_value?: number
|
||||||
sint_value?: number,
|
sint_value?: number
|
||||||
bool_value?: boolean
|
bool_value?: boolean
|
||||||
}): string | number | undefined | boolean {
|
}): string | number | undefined | boolean {
|
||||||
if (v.string_value !== "") {
|
if (v.string_value !== "") {
|
||||||
|
@ -339,41 +387,42 @@ message Tile {
|
||||||
return v.bool_value
|
return v.bool_value
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private downloadSync() {
|
private downloadSync() {
|
||||||
this.download().then(d => {
|
this.download()
|
||||||
|
.then((d) => {
|
||||||
if (d.length === 0) {
|
if (d.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return this._features.setData(d)
|
return this._features.setData(d)
|
||||||
}).catch(e => {
|
})
|
||||||
|
.catch((e) => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async download(): Promise<Feature[]> {
|
private async download(): Promise<GeojsonFeature[]> {
|
||||||
const result = await fetch(this._url)
|
const result = await fetch(this._url)
|
||||||
if (result.status !== 200) {
|
if (result.status !== 200) {
|
||||||
console.error("Could not download tile " + this._url)
|
console.error("Could not download tile " + this._url)
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
const buffer = await result.arrayBuffer()
|
const buffer = await result.arrayBuffer()
|
||||||
const data = MvtSource.tile_schema.read(new Pbf(buffer))
|
const data = Tile.read(new Pbf(buffer), undefined)
|
||||||
const layers = data.layers
|
const layers = data.layers
|
||||||
let layer = data.layers[0]
|
let layer = data.layers[0]
|
||||||
if (layers.length > 1) {
|
if (layers.length > 1) {
|
||||||
if (!this._layerName) {
|
if (!this._layerName) {
|
||||||
throw "Multiple layers in the downloaded tile, but no layername is given to choose from"
|
throw "Multiple layers in the downloaded tile, but no layername is given to choose from"
|
||||||
}
|
}
|
||||||
layer = layers.find(l => l.name === this._layerName)
|
layer = layers.find((l) => l.name === this._layerName)
|
||||||
}
|
}
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
const builder = new MvtFeatureBuilder(layer.extent, this.x, this.y, this.z)
|
const builder = new MvtFeatureBuilder(layer.extent, this.x, this.y, this.z)
|
||||||
const features: Feature[] = []
|
const features: GeojsonFeature[] = []
|
||||||
|
|
||||||
for (const feature of layer.features) {
|
for (const feature of layer.features) {
|
||||||
const properties = this.inflateProperties(feature.tags, layer.keys, layer.values)
|
const properties = this.inflateProperties(feature.tags, layer.keys, layer.values)
|
||||||
|
@ -383,7 +432,6 @@ message Tile {
|
||||||
return features
|
return features
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private inflateProperties(tags: number[], keys: string[], values: { string_value: string }[]) {
|
private inflateProperties(tags: number[], keys: string[], values: { string_value: string }[]) {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
for (let i = 0; i < tags.length; i += 2) {
|
for (let i = 0; i < tags.length; i += 2) {
|
||||||
|
@ -407,5 +455,4 @@ message Tile {
|
||||||
|
|
||||||
return properties
|
return properties
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
No tests
|
No tests
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,6 +4,8 @@ import ThemeViewGUI from "./src/UI/ThemeViewGUI.svelte"
|
||||||
import LayoutConfig from "./src/Models/ThemeConfig/LayoutConfig";
|
import LayoutConfig from "./src/Models/ThemeConfig/LayoutConfig";
|
||||||
import MetaTagging from "./src/Logic/MetaTagging";
|
import MetaTagging from "./src/Logic/MetaTagging";
|
||||||
import { FixedUiElement } from "./src/UI/Base/FixedUiElement";
|
import { FixedUiElement } from "./src/UI/Base/FixedUiElement";
|
||||||
|
import { Utils } from "./src/Utils"
|
||||||
|
import Constants from "./src/Models/Constants"
|
||||||
|
|
||||||
function webgl_support() {
|
function webgl_support() {
|
||||||
try {
|
try {
|
||||||
|
@ -16,13 +18,27 @@ function webgl_support() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async function getAvailableLayers(): Promise<Set<string>> {
|
||||||
|
try {
|
||||||
|
const host = new URL(Constants.VectorTileServer).host
|
||||||
|
const status = await Utils.downloadJson("https://" + host + "/summary/status.json")
|
||||||
|
return new Set<string>(status.layers)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Could not get MVT available layers due to", e)
|
||||||
|
return new Set<string>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
if (!webgl_support()) {
|
if (!webgl_support()) {
|
||||||
new FixedUiElement("WebGL is not supported or not enabled. This is essential for MapComplete to function, please enable this.").SetClass("block alert").AttachTo("maindiv")
|
new FixedUiElement("WebGL is not supported or not enabled. This is essential for MapComplete to function, please enable this.").SetClass("block alert").AttachTo("maindiv")
|
||||||
}else{
|
}else{
|
||||||
|
const availableLayers = await getAvailableLayers()
|
||||||
MetaTagging.setThemeMetatagging(new ThemeMetaTagging())
|
MetaTagging.setThemeMetatagging(new ThemeMetaTagging())
|
||||||
// LAYOUT.ADD_LAYERS
|
// LAYOUT.ADD_LAYERS
|
||||||
const state = new ThemeViewState(new LayoutConfig(<any> layout))
|
const state = new ThemeViewState(new LayoutConfig(<any> layout), availableLayers)
|
||||||
const main = new SvelteUIElement(ThemeViewGUI, { state })
|
const main = new SvelteUIElement(ThemeViewGUI, { state })
|
||||||
main.AttachTo("maindiv")
|
main.AttachTo("maindiv")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
main()
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import SvelteUIElement from "./UI/Base/SvelteUIElement"
|
import SvelteUIElement from "./UI/Base/SvelteUIElement"
|
||||||
import Test from "./UI/Test.svelte"
|
import Test from "./UI/Test.svelte"
|
||||||
|
import MvtSource from "./Logic/FeatureSource/Sources/MvtSource"
|
||||||
|
|
||||||
|
new MvtSource("https://example.org", undefined, undefined, undefined)
|
||||||
|
|
||||||
new SvelteUIElement(Test, {}).AttachTo("maindiv")
|
new SvelteUIElement(Test, {}).AttachTo("maindiv")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue