Comments (11)
For reference, here are two fully-working versions that aren't webpack-specific (pardon the @type
comment syntax for TypeScript types):
without a worker
<canvas id="harpCanvas"></canvas>
<style>
#harpCanvas {
width: 500px;
height: 300px;
padding: 0;
border: 0;
}
</style>
import { MapView } from "@here/harp-mapview";
import { GeoCoordinates } from "@here/harp-geoutils";
import {
APIFormat,
AuthenticationMethod,
OmvDataSource
} from "@here/harp-omv-datasource";
import { OmvTileDecoder } from "@here/harp-omv-datasource/index-worker";
import { MapControls } from "@here/harp-map-controls";
const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById(
"harpCanvas"
));
const mapView = new MapView({
canvas,
theme:
"https://unpkg.com/@here/[email protected]/resources/berlin_tilezen_base.json",
/**
* This is the part I was confused with: ignore these options, instead
* set the 'decoder' option in the 'OmvDataSource', see below.
*/
// decoderUrl: "harp-gl-decoders.bundle.js",
// decoderCount: 0,
maxVisibleDataSourceTiles: 40,
tileCacheSize: 100
});
mapView.camera.position.set(0, 0, 800);
mapView.geoCenter = new GeoCoordinates(40.70398928, -74.01319808, 0);
mapView.resize(canvas.clientWidth, canvas.clientHeight);
const dataSource = new OmvDataSource({
apiFormat: APIFormat.XYZOMV,
styleSetName: "tilezen",
baseUrl: "https://vector.hereapi.com/v2/vectortiles/base/mc",
authenticationCode: "YOUR_API_KEY_HERE",
authenticationMethod: {
method: AuthenticationMethod.QueryString,
name: "apikey"
},
// This here! Set this to disable workers and make it load in the same thread (I
// haven't noticed any performance issue on my slow intel i5 laptop).
decoder: new OmvTileDecoder()
});
mapView.addDataSource(dataSource);
MapControls.create(mapView);
with a worker
<canvas id="harpCanvas"></canvas>
<style>
#harpCanvas {
width: 500px;
height: 300px;
padding: 0;
border: 0;
}
</style>
import { MapView } from "@here/harp-mapview";
import { GeoCoordinates } from "@here/harp-geoutils";
import {
APIFormat,
AuthenticationMethod,
OmvDataSource
} from "@here/harp-omv-datasource";
import { MapControls, MapControlsUI } from "@here/harp-map-controls";
// import OmvTileDecoderService inside a web Worker with vanilla JS, thanks to
// the JSPM ES Module CDN (https://jspm.io).
const workerCode = `
async function main() {
const { OmvTileDecoderService } = (
await import('https://dev.jspm.io/@here/harp-omv-datasource/index-worker')
).default
OmvTileDecoderService.start()
}
main()
`;
const blob = new Blob([workerCode], { type: "application/javascript" });
const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById(
"harpCanvas"
));
const map = new MapView({
canvas,
theme:
"https://unpkg.com/@here/[email protected]/resources/berlin_tilezen_base.json",
decoderUrl: URL.createObjectURL(blob),
// For tile cache optimization:
maxVisibleDataSourceTiles: 40,
tileCacheSize: 100
});
map.setCameraGeolocationAndZoom(
new GeoCoordinates(1.278676, 103.850216),
16
);
const mapControls = new MapControls(map);
const ui = new MapControlsUI(mapControls);
canvas.parentElement.appendChild(ui.domElement);
map.resize(canvas.clientWidth, canvas.clientHeight);
const omvDataSource = new OmvDataSource({
baseUrl: "https://vector.hereapi.com/v2/vectortiles/base/mc",
authenticationCode: "YOUR_API_KEY_HERE",
authenticationMethod: {
method: AuthenticationMethod.QueryString,
name: "apikey"
},
apiFormat: APIFormat.XYZOMV,
styleSetName: "tilezen"
});
map.addDataSource(omvDataSource);
from harp.gl.
Ah, I see. It wasn't obvious from the docs that we could pass an instance to decoder, decoder: new OmvTileDecoder()
.
Anywho, I got the worker working (above) with native ES Module imports inside the worker using import('https://dev.jspm.io/@here/harp-omv-datasource/index-worker')
, so I no longer need to try the non-worker version (though good to know!).
EDIT: Aah, I got confused with decoder*
options of MapView
, which is what I was fiddling, and I didn't realize I needed to set an option for the OmvDataSource
).
from harp.gl.
As an example, take into consideration web applications that use native ES Modules, with no build steps.
ES Modules inside Web Workers are out now.
from harp.gl.
As a related question, how do we run without a worker? I tried
const canvas = document.getElementById("harpCanvas");
const mapView = new MapView({
canvas,
theme:
"https://unpkg.com/@here/[email protected]/resources/berlin_tilezen_base.json"
// decoderUrl: "harp-gl-decoders.bundle.js"
});
mapView.camera.position.set(0, 0, 800);
mapView.geoCenter = new GeoCoordinates(40.70398928, -74.01319808, 0);
mapView.resize(canvas.clientWidth, canvas.clientHeight);
const dataSource = new OmvDataSource({
baseUrl: "https://vector.hereapi.com/v2/vectortiles/base/mc",
apiFormat: APIFormat.XYZOMV,
styleSetName: "tilezen",
authenticationCode: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
authenticationMethod: {
method: AuthenticationMethod.QueryString,
name: "apikey"
}
});
mapView.addDataSource(dataSource);
MapControls.create(mapView);
but I get the error
MapView: Failed to connect to datasource anonymous-datasource#1: Error during worker initialization: Uncaught SyntaxError: Unexpected token '<' in http://localhost:3000/decoder.bundle.js:1
Because my server sends back a 404 page (HTML page starts with <
).
EDIT: Setting MapView
's decoderCount
to 0
got me further, this time saying TileLoader: [anonymous-datasource#1]: failed to load tile 327439125 Error: ConcurrentWorkerSet#postMessage: no workers started
.
from harp.gl.
I tried the same exact demo as listed on the website's tutorial, but I get the same error. This is the tutorial code:
import { MapView } from "@here/harp-mapview";
import { GeoCoordinates } from "@here/harp-geoutils";
import {
APIFormat,
OmvDataSource
} from "@here/harp-omv-datasource";
import { MapControls, MapControlsUI } from "@here/harp-map-controls";
import { OmvTileDecoderService } from "@here/harp-omv-datasource/index-worker";
const canvas = document.getElementById("harpCanvas");
const map = new MapView({
canvas,
theme:
"https://unpkg.com/@here/[email protected]/resources/berlin_tilezen_base.json",
//For tile cache optimization:
maxVisibleDataSourceTiles: 40,
tileCacheSize: 100
});
map.setCameraGeolocationAndZoom(
new GeoCoordinates(1.278676, 103.850216),
16
);
const mapControls = new MapControls(map);
const ui = new MapControlsUI(mapControls);
canvas.parentElement.appendChild(ui.domElement);
mapControls.maxPitchAngle = 90;
// mapControls.setRotation(6.3, 50);
// mapControls.camera.rotation
map.resize(window.innerWidth, window.innerHeight);
window.onresize = () => map.resize(window.innerWidth, window.innerHeight);
const omvDataSource = new OmvDataSource({
baseUrl: "https://xyz.api.here.com/tiles/herebase.02",
apiFormat: APIFormat.XYZOMV,
styleSetName: "tilezen",
authenticationCode: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
});
map.addDataSource(omvDataSource);
Also I get an error that mapControls.setRotation
doesn't exist, it is an undefined
property.
from harp.gl.
I think what could be a nice solution would be to publish the output code in ESM format. Then people could import that file directly in the worker by import
ing it from unpkg
or from locally-served node_modules, for example, without build steps.
EDIT: Plus! If everything is published as ES Modules, this also improves Webpack tree shaking for people who go that route.
from harp.gl.
Well how about that! Google Chrome's native ES Modules can load OmvTileDecoderService
in a web worker directly from JSPM's ES Module CDN (which ports mostly anything found on NPM to ES Modules).
Try running this in your browser console and wait for the worker to log the OmvTileDecoderService
class to console:
// import OmvTileDecoderService inside a web Worker with vanilla JS, thanks to
// the JSPM ES Module CDN (https://jspm.io).
{
const workerCode = `
import HarpOmvDatasource from 'https://dev.jspm.io/@here/harp-omv-datasource/index-worker'
console.log(HarpOmvDatasource.OmvTileDecoderService)
`;
const blob = new Blob([workerCode], {type: 'application/javascript'});
const worker = new Worker(URL.createObjectURL(blob), {type: 'module'});
}
Now, I need to figure how to make the main thread Harp code not try to load decoder.bundle.js
and use the custom-made worker.
Note, I do see the main thread sends this message:
{
service: "worker-service-manager",
type: "initialized"
}
Any tips?
from harp.gl.
Ah! The key is decoderUrl
, which can take the blob URL. So this gets me further:
const workerCode = `
import HarpOmvDatasource from 'https://dev.jspm.io/@here/harp-omv-datasource/index-worker'
const { OmvTileDecoderService } = HarpOmvDatasource
console.log('IN WORKER!!', OmvTileDecoderService)
OmvTileDecoderService.start()
`;
const blob = new Blob([workerCode], { type: "application/javascript" });
const canvas = document.getElementById("harpCanvas");
const map = new MapView({
canvas,
theme: "https://unpkg.com/@here/[email protected]/resources/berlin_tilezen_base.json",
decoderUrl: URL.createObjectURL(blob),
});
But now the problem is,
MapView: Failed to connect to datasource anonymous-datasource#1: Error during worker initialization: Uncaught SyntaxError: Cannot use import statement outside a module in blob:http://localhost:3000/41ff4879-b970-441b-a190-15172a2a87cd:2
Because internally MapView
is not making the web worker with {type: 'module'}
. That would be an easy fix to the harp.gl source...
from harp.gl.
Okay! I got past that error by using the import()
function instead of the import
syntax, thus not requiring MapView
to instantiate the web worker with {type: 'module'}
. Like this:
const workerCode = `
async function main() {
const { OmvTileDecoderService } = (
await import('https://dev.jspm.io/@here/harp-omv-datasource/index-worker')
).default
OmvTileDecoderService.start()
}
main()
`;
const blob = new Blob([workerCode], { type: "application/javascript" });
const canvas = document.getElementById("harpCanvas");
const map = new MapView({
canvas,
theme: "https://unpkg.com/@here/[email protected]/resources/berlin_tilezen_base.json",
decoderUrl: URL.createObjectURL(blob),
});
However now I'm getting HTTP 401 errors from the Here API (https://xyz.api.here.com/tiles/herebase.02/14), although I did enter my API key, but that's a totally different problem than in this issue.
So, for anyone not running with Webpack, the above should get them running, assuming other stuff like API access works.
from harp.gl.
@trusktr , thanks for your indepth research! I'm not an expert on webpack, so I have asked in our internal chat to find someone who can perhaps give you a more informed opinion.
Just one comment, you asked above:
As a related question, how do we run without a worker?
Here is a DataSource that runs in the main thread, it isn't a long term solution, but for debugging etc, it can be helpful to get something up and running quickly, note the decoder
parameter.
const omvDataSource = new OmvDataSource({
baseUrl: "https://vector.hereapi.com/v2/vectortiles/base/mc",
apiFormat: APIFormat.XYZOMV,
styleSetName: "tilezen",
maxZoomLevel: 17,
authenticationCode: apikey,
authenticationMethod: {
method: AuthenticationMethod.QueryString,
name: "apikey"
},
copyrightInfo,
decoder: new OmvTileDecoder()
});
from harp.gl.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
from harp.gl.
Related Issues (20)
- Give 3D buildings that have 0m height data a random height between 2 values HOT 2
- Load building height data from different sources and combining with Here Maps (ex. Open Street Maps - OSM) HOT 2
- Allow CirclesTechnique points size to be specified in metres and pixels HOT 1
- MapView: Failed to connect to geojson: Error during worker initialization HOT 7
- Getting Started Guide is broken HOT 9
- Some countries has no shaped data at all HOT 2
- Maintaining "North up" in Spherical Map HOT 3
- big polygon broken in some levelοΌ HOT 2
- Optimisation possible for rendering. Only evaluate expressions for items which are in viewport. HOT 1
- Can I use anotherdata server? HOT 2
- Drawing exception problem HOT 4
- [feature] time-based tools HOT 3
- Equirectangular Tiles supported? HOT 3
- reactjs examples that work with current version of Harp HOT 8
- GeoJson is not being extruded. HOT 2
- Heatmap example is blank HOT 5
- Uncaught ReferenceError: THREE is not defined HOT 8
- Help with custom shader water layer HOT 4
- Docs and online examples is 404 HOT 3
- Do existing harp.gl users need to make any changes to match the new change? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from harp.gl.