Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
web-et-numerique
web-et-numerique-internet
data.grandlyon.com
web-portal
components
custom-apps
web-app
Commits
c798f80e
Commit
c798f80e
authored
Aug 02, 2018
by
ncastejon
Browse files
WIP big datasets
parent
28ccf9a3
Changes
10
Hide whitespace changes
Inline
Side-by-side
package-lock.json
View file @
c798f80e
...
...
@@ -15177,7 +15177,6 @@
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"dev": true,
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
...
...
@@ -15186,16 +15185,14 @@
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
}
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
"dev": true
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
},
"xmlhttprequest-ssl": {
"version": "1.5.5",
...
...
package.json
View file @
c798f80e
...
...
@@ -41,7 +41,8 @@
"
mapbox-gl
"
:
"
^0.45.0
"
,
"
ng-inline-svg
"
:
"
^8.0.1
"
,
"
ngx-infinite-scroll
"
:
"
^6.0.1
"
,
"
rxjs
"
:
"
^6.2.2
"
,
"
rxjs
"
:
"
^6.2.0
"
,
"
xml2js
"
:
"
^0.4.19
"
,
"
zone.js
"
:
"
^0.8.26
"
},
"devDependencies"
:
{
...
...
src/app/core/handlers/errors-handler.ts
View file @
c798f80e
...
...
@@ -4,6 +4,7 @@ import { ErrorHandler, Injectable } from '@angular/core';
export
class
ErrorsHandler
implements
ErrorHandler
{
handleError
(
error
:
Error
)
{
console
.
log
(
error
);
return
;
}
...
...
src/app/core/interceptors/http-error-response-interceptor.ts
View file @
c798f80e
...
...
@@ -18,6 +18,7 @@ export class HttpErrorResponseInterceptor implements HttpInterceptor {
}
},
(
err
)
=>
{
console
.
log
(
err
);
if
(
err
instanceof
HttpErrorResponse
)
{
switch
(
err
.
status
)
{
case
401
:
...
...
src/app/core/services/error.service.ts
View file @
c798f80e
...
...
@@ -11,6 +11,7 @@ export class ErrorService {
)
{
}
handleError
(
err
,
opt
):
Error
|
HttpErrorResponse
{
console
.
log
(
err
);
let
error
=
err
;
if
((
err
instanceof
HttpErrorResponse
))
{
switch
(
err
.
status
)
{
...
...
src/app/geosource/components/dataset-detail/dataset-detail.component.ts
View file @
c798f80e
...
...
@@ -49,6 +49,7 @@ export class DatasetDetailComponent implements OnInit {
this
.
metadata
=
this
.
_datasetDetailService
.
datasetMetadata
;
},
(
err
)
=>
{
console
.
log
(
err
);
this
.
_notificationService
.
notify
(
new
Notification
({
message
:
err
.
message
,
type
:
'
error
'
,
...
...
src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.ts
View file @
c798f80e
import
{
Component
,
OnInit
,
OnDestroy
}
from
'
@angular/core
'
;
import
*
as
mapboxgl
from
'
mapbox-gl
'
;
import
{
Metadata
,
IMetadataLink
}
from
'
../../../models
'
;
import
{
DatasetDetailService
}
from
'
../../../services
'
;
import
{
DatasetDetailService
,
MapService
}
from
'
../../../services
'
;
import
{
Subscription
}
from
'
rxjs
'
;
import
{
environment
}
from
'
./../../../../../environments/environment
'
;
import
{
Minimap
}
from
'
./minimap-control
'
;
import
{
NotificationService
}
from
'
../../../../core/services
'
;
import
{
Notification
}
from
'
../../../../core/models
'
;
import
{
errors
}
from
'
../../../../../i18n/error-messages/error-messages.fr
'
;
import
{
HttpEvent
,
HttpEventType
}
from
'
@angular/common/http
'
;
@
Component
({
selector
:
'
app-dataset-map
'
,
...
...
@@ -36,6 +37,9 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
displayControls
=
false
;
mapIsConstructed
=
false
;
geojson
:
GeoJSON
.
FeatureCollection
;
percentageLoading
=
0
;
// When the styles are changed, we don't want add new events each time
eventPopupAdded
=
false
;
...
...
@@ -44,6 +48,7 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
constructor
(
private
_datasetDetailService
:
DatasetDetailService
,
private
_notificationService
:
NotificationService
,
private
_mapService
:
MapService
,
)
{
}
ngOnInit
()
{
...
...
@@ -102,6 +107,7 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
// Create the map with the associated style Mapbox file
this
.
map
=
new
mapboxgl
.
Map
(
options
).
on
(
'
error
'
,
(
error
)
=>
{
console
.
log
(
error
);
this
.
_notificationService
.
notify
(
new
Notification
({
message
:
errors
.
geosource
.
mapError
,
type
:
'
error
'
,
...
...
@@ -125,8 +131,13 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
{
style
:
`assets/mapbox-gl-styles/
${
this
.
selectedBaseLayer
.
fileName
}
`
,
classes
:
'
is-hidden-mobile
'
,
<<<<<<<
HEAD
}),
);
=======
}));
>>>>>>>
WIP
big
datasets
}
});
...
...
@@ -135,12 +146,79 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
this
.
map
.
on
(
'
style.load
'
,
()
=>
{
// Check if the metadata has WFS (vector) data format. If not we use WMS format
const
uriWFS
=
this
.
metadata
.
link
.
find
((
e
)
=>
{
return
e
.
protocol
===
'
OGC:WFS
'
;
});
if
(
uriWFS
)
{
this
.
addWFSLayer
(
uriWFS
);
if
(
uriWFS
&&
this
.
_datasetDetailService
.
datasetDataNumber
<
100000
)
{
// let loaded = 1;
// let size = 0;
const
loadParts
=
Math
.
floor
(
this
.
_datasetDetailService
.
datasetDataNumber
/
5000
);
const
bounds
=
this
.
map
.
getBounds
();
const
bbox
=
''
+
bounds
.
getSouthWest
().
lat
+
'
,
'
+
bounds
.
getSouthWest
().
lng
+
'
,
'
+
bounds
.
getNorthEast
().
lat
+
'
,
'
+
bounds
.
getNorthEast
().
lng
;
this
.
_mapService
.
getWFSFeatures
(
uriWFS
,
0
,
1000
,
bbox
).
subscribe
((
geojson
)
=>
{
// switch (event.type) {
// case HttpEventType.Sent:
// console.log('Request sent!');
// break;
// case HttpEventType.ResponseHeader:
// console.log('Response header received!');
// break;
// case HttpEventType.DownloadProgress:
// const kbLoaded = Math.round(event.loaded / 1024);
// this.percentageLoading = Math.round(100 * event.loaded / event.total);
// console.log(`Download in progress! ${kbLoaded}Kb loaded`);
// break;
// case HttpEventType.Response:
// console.log(event);
// this.geojson = event.body;
// this.addWFSLayer(event.body);
// console.log('😺 Done!', event.body);
// }
this
.
addWFSLayer
(
geojson
);
});
// for (let i = 1; i <= loadParts; i += 1) {
// this._mapService.getWFSFeatures(uriWFS, size, 5000).subscribe((geojson) => {
// this.geojson.features = this.geojson.features.concat(geojson.features);
// const source = this.map.getSource('wfs-clustered-points') as mapboxgl.GeoJSONSource;
// source.setData(this.geojson);
// loaded += 1;
// console.log(i);
// console.log(loadParts);
// this.percentageLoading = Math.floor(loaded * 5000 / this._datasetDetailService.datasetDataNumber * 100);
// if (i === loadParts) {
// this.percentageLoading = 100;
// }
// });
// size = size + 5000;
// }
}
else
{
const
uriWMS
=
this
.
metadata
.
link
.
find
((
e
)
=>
{
return
e
.
protocol
===
'
OGC:WMS
'
;
});
this
.
addWMSLayer
(
uriWMS
);
}
this
.
map
.
on
(
'
zoomend
'
,
()
=>
{
const
bounds
=
this
.
map
.
getBounds
();
const
bbox
=
''
+
bounds
.
getSouthWest
().
lat
+
'
,
'
+
bounds
.
getSouthWest
().
lng
+
'
,
'
+
bounds
.
getNorthEast
().
lat
+
'
,
'
+
bounds
.
getNorthEast
().
lng
;
this
.
_mapService
.
getWFSFeatures
(
uriWFS
,
0
,
1000
,
bbox
).
subscribe
((
geojson
)
=>
{
const
source
=
this
.
map
.
getSource
(
'
wfs-clustered-points
'
)
as
mapboxgl
.
GeoJSONSource
;
source
.
setData
(
geojson
);
});
});
this
.
map
.
on
(
'
move
'
,
()
=>
{
const
bounds
=
this
.
map
.
getBounds
();
const
bbox
=
''
+
bounds
.
getSouthWest
().
lat
+
'
,
'
+
bounds
.
getSouthWest
().
lng
+
'
,
'
+
bounds
.
getNorthEast
().
lat
+
'
,
'
+
bounds
.
getNorthEast
().
lng
;
this
.
_mapService
.
getWFSFeatures
(
uriWFS
,
0
,
1000
,
bbox
).
subscribe
((
geojson
)
=>
{
const
source
=
this
.
map
.
getSource
(
'
wfs-clustered-points
'
)
as
mapboxgl
.
GeoJSONSource
;
source
.
setData
(
geojson
);
});
});
});
}
}
...
...
@@ -173,12 +251,10 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
// - add the source (url where to fetch the data)
// - create layers from the source
// - if the features are 'Point', create clustering layers
addWFSLayer
(
uriWFS
:
IMetadataLink
)
{
addWFSLayer
(
geojson
:
GeoJSON
.
FeatureCollection
)
{
this
.
map
.
addSource
(
'
wfs-clustered-points
'
,
{
type
:
'
geojson
'
,
data
:
uriWFS
.
url
+
'
?SERVICE=WFS&VERSION=2.0.0
'
+
'
&outputformat=GEOJSON&maxfeatures=1000&request=GetFeature&typename=
'
+
uriWFS
.
name
+
'
&srsname=EPSG:4326&
'
+
'
,EPSG:4326
'
,
data
:
geojson
,
cluster
:
true
,
clusterMaxZoom
:
13
,
// Max zoom to cluster points on
clusterRadius
:
45
,
// Radius of each cluster when clustering points (defaults to 50)
...
...
@@ -186,9 +262,7 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
this
.
map
.
addSource
(
'
wfs-polygon
'
,
{
type
:
'
geojson
'
,
data
:
uriWFS
.
url
+
'
?SERVICE=WFS&VERSION=2.0.0
'
+
'
&outputformat=GEOJSON&maxfeatures=1000&request=GetFeature&typename=
'
+
uriWFS
.
name
+
'
&srsname=EPSG:4326&
'
+
'
,EPSG:4326
'
,
data
:
geojson
,
});
// Add the layers for 'Point' features (clustered and unclustered layers)
...
...
@@ -259,6 +333,7 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
'
text-halo-width
'
:
2
,
},
});
});
// For 'Polygon' feature, one layer is enough (no cluster)
...
...
@@ -347,6 +422,18 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
source
:
'
WMS
'
,
paint
:
{},
});
this
.
map
.
on
(
'
click
'
,
(
e
)
=>
{
console
.
log
(
e
);
const
features
=
this
.
map
.
queryRenderedFeatures
(
e
.
point
);
console
.
log
(
features
);
const
bounds
=
this
.
map
.
getBounds
();
const
bbox
=
''
+
bounds
.
getSouthWest
().
lat
+
'
,
'
+
bounds
.
getSouthWest
().
lng
+
'
,
'
+
bounds
.
getNorthEast
().
lat
+
'
,
'
+
bounds
.
getNorthEast
().
lng
;
const
result
=
this
.
_mapService
.
getFeatureInfo
(
uriWMS
.
name
,
bbox
,
e
.
point
.
x
,
e
.
point
.
y
).
subscribe
((
result
)
=>
{
console
.
log
(
result
);
});
});
}
switch3DLayer
()
{
...
...
@@ -394,8 +481,6 @@ export class DatasetMapComponent implements OnInit, OnDestroy {
// Display inside the popup the key-value properties of the feature
createPopupContent
(
e
:
any
)
{
const
features
=
this
.
map
.
queryRenderedFeatures
(
e
.
point
);
const
coordinates
=
e
.
features
[
0
].
geometry
.
coordinates
.
slice
();
let
content
=
'
<h4>Informations</h4>
'
;
for
(
const
property
in
e
.
features
[
0
].
properties
)
{
...
...
src/app/geosource/services/index.ts
View file @
c798f80e
import
{
DatasetResearchService
}
from
'
./dataset-research.service
'
;
import
{
DatasetDetailService
}
from
'
./dataset-detail.service
'
;
import
{
ElasticsearchService
}
from
'
./elasticsearch.service
'
;
import
{
MapService
}
from
'
./map.service
'
;
export
{
DatasetResearchService
,
DatasetDetailService
,
ElasticsearchService
};
export
{
DatasetResearchService
,
DatasetDetailService
,
ElasticsearchService
,
MapService
};
// tslint:disable-next-line:variable-name
export
const
GeosourceServices
=
[
DatasetResearchService
,
DatasetDetailService
,
ElasticsearchService
,
MapService
,
];
src/app/geosource/services/map.service.ts
0 → 100644
View file @
c798f80e
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
Observable
}
from
'
rxjs
'
;
import
{
HttpClient
,
HttpRequest
}
from
'
@angular/common/http
'
;
import
{
IMetadataLink
}
from
'
../models
'
;
import
{
LngLatBounds
}
from
'
mapbox-gl
'
;
import
{
map
}
from
'
rxjs/operators
'
;
@
Injectable
()
export
class
MapService
{
constructor
(
private
_http
:
HttpClient
,
)
{
}
getWFSFeatures
(
uriWFS
:
IMetadataLink
,
startindex
:
number
,
count
:
number
,
bbox
:
string
)
{
let
url
=
uriWFS
.
url
+
'
?SERVICE=WFS&VERSION=2.0.0
'
+
'
&outputformat=GEOJSON&maxfeatures=100000&request=GetFeature&typename=
'
+
uriWFS
.
name
+
'
&srsname=EPSG:4326&
'
+
'
,EPSG:4326&startindex=
'
+
startindex
+
'
&count=
'
+
count
;
if
(
bbox
)
{
url
=
url
+
'
&bbox=
'
+
bbox
;
}
return
this
.
_http
.
get
<
GeoJSON
.
FeatureCollection
>
(
url
);
}
getFeatureInfo
(
layer
,
bbox
,
x
,
y
)
{
const
url
=
'
https://download.data.grandlyon.com/wms/grandlyon?request=GetFeatureInfo
'
+
'
&service=WMS
'
+
'
&version=1.1.1
'
+
'
&layers=
'
+
layer
+
'
&srs=EPSG:3857
'
+
'
&width=780
'
+
'
&height=330
'
+
'
&bbox=
'
+
bbox
+
'
&query_layers=
'
+
layer
+
'
&info_format=text/plain
'
+
'
&feature_count=1
'
+
'
&x=
'
+
x
+
'
&y=
'
+
y
;
return
this
.
_http
.
get
(
url
).
pipe
(
map
((
xml
)
=>
{
// const parseString = require('xml2js').parseString;
// return parseString(xml, (err, result) => {
// return result;
// });
}));
}
}
src/styles.scss
View file @
c798f80e
...
...
@@ -17,18 +17,10 @@ body {
line-height
:
1
.375rem
;
}
.site
{
.site
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
}
.site-content
{
flex
:
1
0
auto
;
}
.site-header
,
.site-footer
{
flex-shrink
:
0
;
display
:
grid
;
grid-template-rows
:
auto
1fr
auto
}
h1
,
h2
,
h3
,
h4
,
h5
,
h6
,
.h1
,
.h2
,
.h3
,
.h4
,
.h5
,
.h6
.card-header-title
,
.navbar
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment