Skip to content

Commit

Permalink
refacto raster
Browse files Browse the repository at this point in the history
  • Loading branch information
gchoqueux committed Jul 5, 2018
1 parent d99d67a commit b458129
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 81 deletions.
60 changes: 32 additions & 28 deletions examples/globe_vector.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,44 +61,48 @@
// Add one imagery layer to the scene
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
promises.push(itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(addLayerCb));
// promises.push(itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(addLayerCb));
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
promises.push(itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addLayerCb));
promises.push(itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addLayerCb));
// promises.push(itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addLayerCb));
// promises.push(itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addLayerCb));

promises.push(globeView.addLayer({
type: 'color',
url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/croquis.kml',
protocol: 'rasterizer',
id: 'Kml',
name: 'kml',
transparent: true,
}));

promises.push(globeView.addLayer({
type: 'color',
url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/ULTRA2009.gpx',
protocol: 'rasterizer',
id: 'Gpx',
name: 'Ultra 2009',
transparent: true,
}));

promises.push(globeView.addLayer({
type: 'color',
url: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson',
protocol: 'rasterizer',
id: 'ariege',
name: 'ariege',
transparent: true,
style: {
fill: 'orange',
fillOpacity: 0.5,
stroke: 'white',
source: {
protocol: 'file',
url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/croquis.kml',
},
}));

// promises.push(globeView.addLayer({
// type: 'color',
// id: 'Gpx',
// name: 'Ultra 2009',
// transparent: true,
// source: {
// url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/ULTRA2009.gpx',
// protocol: 'file',
// },
// }));

// promises.push(globeView.addLayer({
// type: 'color',
// url: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/09-ariege/departement-09-ariege.geojson',
// protocol: 'rasterizer',
// id: 'ariege',
// name: 'ariege',
// transparent: true,
// style: {
// fill: 'orange',
// fillOpacity: 0.5,
// stroke: 'white',
// },
// }));

var menuGlobe = new GuiTools('menuDiv', globeView);

// Listen for globe full initialisation event
Expand All @@ -108,7 +112,7 @@
Promise.all(promises).then(function () {
menuGlobe.addImageryLayersGUI(globeView.getLayers(function (l) { return l.type === 'color'; }));
menuGlobe.addElevationLayersGUI(globeView.getLayers(function (l) { return l.type === 'elevation'; }));
itowns.ColorLayersOrdering.moveLayerToIndex(globeView, 'Ortho', 0);
// itowns.ColorLayersOrdering.moveLayerToIndex(globeView, 'Ortho', 0);

new ToolTip(globeView, document.getElementById('viewerDiv'), document.getElementById('tooltipDiv'));
}).catch(console.error);
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Scheduler/Scheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Scheduler.prototype.initDefaultProviders = function initDefaultProviders() {
this.addProtocolProvider('xyz', TMSProvider);
this.addProtocolProvider('potreeconverter', PointCloudProvider);
this.addProtocolProvider('wfs', WFSProvider);
this.addProtocolProvider('rasterizer', RasterProvider);
this.addProtocolProvider('file', RasterProvider);
this.addProtocolProvider('static', StaticProvider);
};

Expand Down
2 changes: 1 addition & 1 deletion src/Core/TileMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ TileMesh.prototype.changeSequenceLayers = function changeSequenceLayers(sequence
};

TileMesh.prototype.getCoordsForLayer = function getCoordsForLayer(layer) {
if (layer.protocol.indexOf('wmts') == 0) {
if (layer.protocol.indexOf('wmts') == 0 /* || layer.protocol.indexOf('file') == 0 */) {
const source = layer;
OGCWebServiceHelper.computeTileMatrixSetCoordinates(this, source.tileMatrixSet);
return this.wmtsCoords[source.tileMatrixSet];
Expand Down
20 changes: 15 additions & 5 deletions src/Core/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Scheduler from './Scheduler/Scheduler';
import Picking from './Picking';
import { updateLayeredMaterialNodeImagery, updateLayeredMaterialNodeElevation } from '../Process/LayeredMaterialNodeProcessing';
import WMTSSource from '../Source/WMTSSource';
import geoFileSource from '../Source/geoFileSource';
import textureConverter from '../Parser/textureConverter';

export const VIEW_EVENTS = {
Expand Down Expand Up @@ -145,16 +146,18 @@ function _preprocessLayer(view, layer, provider, parentLayer) {
};
}

layer.style = layer.style || {};

// temp
// devrait etre supprime et placer dans source
if (provider && !layer.source) {
if (provider.tileInsideLimit) {
layer.tileInsideLimit = provider.tileInsideLimit.bind(provider);
}

if (provider.tileTextureCount) {
layer.tileTextureCount = provider.tileTextureCount.bind(provider);
}
// ne semble pas etre necessaire
// if (provider.tileTextureCount) {
// layer.tileTextureCount = provider.tileTextureCount.bind(provider);
// }
}

if (!layer.whenReady) {
Expand All @@ -172,7 +175,14 @@ function _preprocessLayer(view, layer, provider, parentLayer) {
providerPreprocessing = Promise.resolve();
}
} else if (layer.source) {
layer.source = new WMTSSource(layer.source);
if (layer.source.protocol === 'wmts') {
layer.source = new WMTSSource(layer.source);
} else if (layer.source.protocol === 'file') {
layer.source = new geoFileSource(layer.source);
layer.noTextureParentOutsideLimit = true;
layer.destination = parentLayer;
providerPreprocessing = layer.source.whenReady;
}
}

// the last promise in the chain must return the layer
Expand Down
4 changes: 3 additions & 1 deletion src/Process/LayeredMaterialNodeProcessing.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function checkNodeElevationTextureValidity(texture, noDataValue) {
// temp
const tileInsideLimit = (node, layer, target, parent, pitch) =>
(layer.source ?
layer.source.extentInsideLimit(node.getCoordsForLayer(layer.source), target, parent, pitch) :
layer.source.extentInsideLimit(node.getCoordsForLayer(layer.source), target, parent, pitch, node.level) :
layer.tileInsideLimit(node, layer, target));

export function updateLayeredMaterialNodeImagery(context, layer, node) {
Expand Down Expand Up @@ -252,6 +252,7 @@ export function updateLayeredMaterialNodeImagery(context, layer, node) {
return;
}


const extents = [];
const pitchs = [];
// Retry tileInsideLimit because you must check with the targetLevel
Expand All @@ -275,6 +276,7 @@ export function updateLayeredMaterialNodeImagery(context, layer, node) {

return context.scheduler.execute(command).then(
(textures) => {

if (node.material === null) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Process/SubdivisionControl.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// temp
const tileInsideLimit = (node, layer, target) =>
(layer.source ?
layer.source.extentInsideLimit(node.getCoordsForLayer(layer.source), target) :
layer.source.extentInsideLimit(node.getCoordsForLayer(layer.source), target, undefined, undefined, node.level) :
layer.tileInsideLimit(node, layer, target));

export default {
Expand Down
99 changes: 55 additions & 44 deletions src/Provider/RasterProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,28 @@
*/


import * as THREE from 'three';
import togeojson from 'togeojson';
import Extent from '../Core/Geographic/Extent';
// import * as THREE from 'three';
// import togeojson from 'togeojson';
// import Extent from '../Core/Geographic/Extent';
import Feature2Texture from '../Renderer/ThreeExtended/Feature2Texture';
import GeoJsonParser from '../Parser/GeoJsonParser';
import Fetcher from './Fetcher';

function getExtentFromGpxFile(file) {
const bound = file.getElementsByTagName('bounds')[0];
if (bound) {
const west = bound.getAttribute('minlon');
const east = bound.getAttribute('maxlon');
const south = bound.getAttribute('minlat');
const north = bound.getAttribute('maxlat');
return new Extent('EPSG:4326', west, east, south, north);
}
return new Extent('EPSG:4326', -180, 180, -90, 90);
}

function createTextureFromVector(tile, layer) {
if (!tile.material) {
return Promise.resolve();
}

if (layer.type == 'color') {
const coords = tile.extent;
const result = { pitch: new THREE.Vector4(0, 0, 1, 1) };
result.texture = Feature2Texture.createTextureFromFeature(layer.feature, tile.extent, 256, layer.style);
result.texture.extent = tile.extent;
result.texture.coords = coords;
result.texture.coords.zoom = tile.level;

if (layer.transparent) {
result.texture.premultiplyAlpha = true;
}
return Promise.resolve(result);
} else {
return Promise.resolve();
}
}
// import Fetcher from './Fetcher';

// function getExtentFromGpxFile(file) {
// const bound = file.getElementsByTagName('bounds')[0];
// if (bound) {
// const west = bound.getAttribute('minlon');
// const east = bound.getAttribute('maxlon');
// const south = bound.getAttribute('minlat');
// const north = bound.getAttribute('maxlat');
// return new Extent('EPSG:4326', west, east, south, north);
// }
// return new Extent('EPSG:4326', -180, 180, -90, 90);
// }


export default {
preprocessDataLayer(layer, view, scheduler, parentLayer) {
/* preprocessDataLayer(layer, view, scheduler, parentLayer) {
if (!layer.url) {
throw new Error('layer.url is required');
}
Expand Down Expand Up @@ -117,14 +96,46 @@ export default {
layer.extent = feature.extent;
}
});
},
tileInsideLimit(tile, layer) {
return tile.level >= layer.options.zoom.min && tile.level <= layer.options.zoom.max && layer.extent.intersectsExtent(tile.extent);
},
}, */
// tileInsideLimit(tile, layer) {
// return tile.level >= layer.options.zoom.min && tile.level <= layer.options.zoom.max && layer.extent.intersectsExtent(tile.extent);
// },
executeCommand(command) {
const layer = command.layer;
const tile = command.requester;
// todo à virer
if (!tile.material) {
return Promise.resolve();
}

return createTextureFromVector(tile, layer);
let promise = Promise.resolve();

if (!layer.feature) {
// console.log('build feature');
const options = {
buildExtent: true,
crsIn: layer.projection,
crsOut: layer.destination.extent.crs(),
filteringExtent: layer.extent,
};
promise = GeoJsonParser.parse(layer.source.geojson, options).then((feature) => {
layer.feature = feature;
layer.extent = feature.extent;
layer.source.extent = feature.extent;
});
}

return promise.then(() => {
const texture = Feature2Texture.createTextureFromFeature(layer.feature, tile.extent, 256, layer.style);
// TODO why
texture.extent = tile.extent;
texture.coords = tile.extent;
texture.coords.zoom = tile.level;

if (layer.style.transparent) {
texture.premultiplyAlpha = true;
}
return Promise.resolve([texture]);
});
},
};
84 changes: 84 additions & 0 deletions src/Source/geoFileSource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import togeojson from 'togeojson';
import Fetcher from '../Provider/Fetcher';
import Extent from '../Core/Geographic/Extent';

function getExtentFromGpxFile(file) {
const bound = file.getElementsByTagName('bounds')[0];
if (bound) {
const west = bound.getAttribute('minlon');
const east = bound.getAttribute('maxlon');
const south = bound.getAttribute('minlat');
const north = bound.getAttribute('maxlat');
return new Extent('EPSG:4326', west, east, south, north);
}
return new Extent('EPSG:4326', -180, 180, -90, 90);
}

class geoFileSource {
constructor(source) {
if (!source.url) {
throw new Error('source.url is required');
}

this.protocol = 'file';

this.url = source.url;

this.tileMatrixSet = 'WGS84G';

// KML and GPX specifications all says that they should be in
// EPSG:4326. We still support reprojection for them through this
// configuration option
this.projection = source.projection || 'EPSG:4326';

if (source.extent && !(source.extent instanceof Extent)) {
this.extent = new Extent(this.projection, source.extent);
}

if (!source.zoom) {
this.zoom = { min: 5, max: 21 };
}

this.networkOptions = source.networkOptions || { crossOrigin: 'anonymous' };

this.whenReady = Fetcher.text(this.url, source.networkOptions).then((text) => {
let geojson;
const trimmedText = text.trim();
// We test the start of the string to choose a parser
if (trimmedText.startsWith('<')) {
// if it's an xml file, then it can be kml or gpx
const parser = new DOMParser();
const file = parser.parseFromString(text, 'application/xml');
if (file.documentElement.tagName.toLowerCase() === 'kml') {
geojson = togeojson.kml(file);
} else if (file.documentElement.tagName.toLowerCase() === 'gpx') {
geojson = togeojson.gpx(file);
geojson.style.stroke = geojson.style.stroke || 'red';
// this.extent = source.extent.intersect(getExtentFromGpxFile(file)); // .as(layer.extent.crs()));
this.extent = getExtentFromGpxFile(file); // .as(layer.extent.crs()));
} else if (file.documentElement.tagName.toLowerCase() === 'parsererror') {
throw new Error('Error parsing XML document');
} else {
throw new Error('Unsupported xml file, only valid KML and GPX are supported, but no <gpx> or <kml> tag found.',
file);
}
} else if (trimmedText.startsWith('{') || trimmedText.startsWith('[')) {
geojson = JSON.parse(text);
if (geojson.type !== 'Feature' && geojson.type !== 'FeatureCollection') {
throw new Error('This json is not a GeoJSON');
}
} else {
throw new Error('Unsupported file: only well-formed KML, GPX or GeoJSON are supported');
}

this.geojson = geojson;
});
}

extentInsideLimit(extent, target, parent, pitch, zoom) {
const result = zoom >= this.zoom.min && zoom <= this.zoom.max && ((this.extent !== undefined && this.extent.intersectsExtent(extent[0])) || this.extent === undefined);
return result;
}
}

export default geoFileSource;

0 comments on commit b458129

Please sign in to comment.