Use IGN plan v2 and add MNHN data sources
This commit is contained in:
parent
f6c4158d9c
commit
bbcdff0ccf
10 changed files with 130 additions and 65 deletions
|
@ -56,30 +56,27 @@ module NewAdministrateur
|
||||||
:updated_at
|
:updated_at
|
||||||
],
|
],
|
||||||
methods: [
|
methods: [
|
||||||
:cadastres,
|
|
||||||
:drop_down_list_value,
|
:drop_down_list_value,
|
||||||
:parcelles_agricoles,
|
|
||||||
:piece_justificative_template_filename,
|
:piece_justificative_template_filename,
|
||||||
:piece_justificative_template_url,
|
:piece_justificative_template_url,
|
||||||
:quartiers_prioritaires
|
:cadastres,
|
||||||
|
:mnhn
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def type_de_champ_create_params
|
def type_de_champ_create_params
|
||||||
type_de_champ_params = params.required(:type_de_champ).permit(:cadastres,
|
type_de_champ_params = params.required(:type_de_champ).permit(:type_champ,
|
||||||
:description,
|
|
||||||
:drop_down_list_value,
|
|
||||||
:libelle,
|
:libelle,
|
||||||
|
:description,
|
||||||
:mandatory,
|
:mandatory,
|
||||||
:order_place,
|
|
||||||
:parcelles_agricoles,
|
|
||||||
:parent_id,
|
:parent_id,
|
||||||
:piece_justificative_template,
|
|
||||||
:private,
|
:private,
|
||||||
:quartiers_prioritaires,
|
:drop_down_list_value,
|
||||||
:type_champ)
|
:piece_justificative_template,
|
||||||
|
:cadastres,
|
||||||
|
:mnhn)
|
||||||
|
|
||||||
if type_de_champ_params[:parent_id].present?
|
if type_de_champ_params[:parent_id].present?
|
||||||
type_de_champ_params[:parent_id] = TypeDeChamp.to_stable_id(type_de_champ_params[:parent_id])
|
type_de_champ_params[:parent_id] = TypeDeChamp.to_stable_id(type_de_champ_params[:parent_id])
|
||||||
|
@ -89,15 +86,14 @@ module NewAdministrateur
|
||||||
end
|
end
|
||||||
|
|
||||||
def type_de_champ_update_params
|
def type_de_champ_update_params
|
||||||
params.required(:type_de_champ).permit(:cadastres,
|
params.required(:type_de_champ).permit(:type_champ,
|
||||||
:description,
|
|
||||||
:drop_down_list_value,
|
|
||||||
:libelle,
|
:libelle,
|
||||||
|
:description,
|
||||||
:mandatory,
|
:mandatory,
|
||||||
:parcelles_agricoles,
|
:drop_down_list_value,
|
||||||
:piece_justificative_template,
|
:piece_justificative_template,
|
||||||
:quartiers_prioritaires,
|
:cadastres,
|
||||||
:type_champ)
|
:mnhn)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,7 @@ import {
|
||||||
|
|
||||||
const Map = ReactMapboxGl({});
|
const Map = ReactMapboxGl({});
|
||||||
|
|
||||||
function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) {
|
function MapEditor({ featureCollection, url, preview, options }) {
|
||||||
const drawControl = useRef(null);
|
const drawControl = useRef(null);
|
||||||
const [currentMap, setCurrentMap] = useState(null);
|
const [currentMap, setCurrentMap] = useState(null);
|
||||||
|
|
||||||
|
@ -35,10 +35,10 @@ function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) {
|
||||||
const [cadastresFeatureCollection, setCadastresFeatureCollection] = useState(
|
const [cadastresFeatureCollection, setCadastresFeatureCollection] = useState(
|
||||||
filterFeatureCollection(featureCollection, 'cadastre')
|
filterFeatureCollection(featureCollection, 'cadastre')
|
||||||
);
|
);
|
||||||
const mapStyle = useMemo(() => getMapStyle(style, hasCadastres), [
|
const mapStyle = useMemo(
|
||||||
style,
|
() => getMapStyle(style, options.cadastres, options.mnhn),
|
||||||
hasCadastres
|
[style, options]
|
||||||
]);
|
);
|
||||||
|
|
||||||
const translations = [
|
const translations = [
|
||||||
['.mapbox-gl-draw_line', 'Tracer une ligne'],
|
['.mapbox-gl-draw_line', 'Tracer une ligne'],
|
||||||
|
@ -306,7 +306,7 @@ function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) {
|
||||||
height: '500px'
|
height: '500px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{hasCadastres ? (
|
{options.cadastres ? (
|
||||||
<GeoJSONLayer
|
<GeoJSONLayer
|
||||||
data={cadastresFeatureCollection}
|
data={cadastresFeatureCollection}
|
||||||
fillPaint={polygonCadastresFill}
|
fillPaint={polygonCadastresFill}
|
||||||
|
@ -326,7 +326,7 @@ function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) {
|
||||||
trash: true
|
trash: true
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<SwitchMapStyle style={style} setStyle={setStyle} ign={ign} />
|
<SwitchMapStyle style={style} setStyle={setStyle} ign={options.ign} />
|
||||||
<ZoomControl />
|
<ZoomControl />
|
||||||
</Map>
|
</Map>
|
||||||
</>
|
</>
|
||||||
|
@ -341,8 +341,11 @@ MapEditor.propTypes = {
|
||||||
}),
|
}),
|
||||||
url: PropTypes.string,
|
url: PropTypes.string,
|
||||||
preview: PropTypes.bool,
|
preview: PropTypes.bool,
|
||||||
hasCadastres: PropTypes.bool,
|
options: PropTypes.shape({
|
||||||
ign: PropTypes.bool
|
cadastres: PropTypes.bool,
|
||||||
|
mnhn: PropTypes.bool,
|
||||||
|
ign: PropTypes.bool
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MapEditor;
|
export default MapEditor;
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
|
|
||||||
const Map = ReactMapboxGl({});
|
const Map = ReactMapboxGl({});
|
||||||
|
|
||||||
const MapReader = ({ featureCollection, ign }) => {
|
const MapReader = ({ featureCollection, options }) => {
|
||||||
const [currentMap, setCurrentMap] = useState(null);
|
const [currentMap, setCurrentMap] = useState(null);
|
||||||
const [style, setStyle] = useState('ortho');
|
const [style, setStyle] = useState('ortho');
|
||||||
const cadastresFeatureCollection = useMemo(
|
const cadastresFeatureCollection = useMemo(
|
||||||
|
@ -52,10 +52,10 @@ const MapReader = ({ featureCollection, ign }) => {
|
||||||
[selectionsUtilisateurFeatureCollection]
|
[selectionsUtilisateurFeatureCollection]
|
||||||
);
|
);
|
||||||
const hasCadastres = !!cadastresFeatureCollection.length;
|
const hasCadastres = !!cadastresFeatureCollection.length;
|
||||||
const mapStyle = useMemo(() => getMapStyle(style, hasCadastres), [
|
const mapStyle = useMemo(
|
||||||
style,
|
() => getMapStyle(style, hasCadastres, options.mnhn),
|
||||||
cadastresFeatureCollection
|
[style, options, cadastresFeatureCollection]
|
||||||
]);
|
);
|
||||||
const popup = useMemo(
|
const popup = useMemo(
|
||||||
() =>
|
() =>
|
||||||
new Popup({
|
new Popup({
|
||||||
|
@ -184,7 +184,7 @@ const MapReader = ({ featureCollection, ign }) => {
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<SwitchMapStyle style={style} setStyle={setStyle} ign={ign} />
|
<SwitchMapStyle style={style} setStyle={setStyle} ign={options.ign} />
|
||||||
<ZoomControl />
|
<ZoomControl />
|
||||||
</Map>
|
</Map>
|
||||||
);
|
);
|
||||||
|
@ -196,7 +196,10 @@ MapReader.propTypes = {
|
||||||
bbox: PropTypes.array,
|
bbox: PropTypes.array,
|
||||||
features: PropTypes.array
|
features: PropTypes.array
|
||||||
}),
|
}),
|
||||||
ign: PropTypes.bool
|
options: PropTypes.shape({
|
||||||
|
ign: PropTypes.bool,
|
||||||
|
mnhn: PropTypes.bool
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MapReader;
|
export default MapReader;
|
||||||
|
|
|
@ -1,15 +1,36 @@
|
||||||
|
const IGN_TOKEN = 'rc1egnbeoss72hxvd143tbyk';
|
||||||
|
|
||||||
|
function ignServiceURL(layer, format = 'image/png') {
|
||||||
|
const url = `https://wxs.ign.fr/${IGN_TOKEN}/geoportail/wmts`;
|
||||||
|
const query =
|
||||||
|
'service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&style=normal';
|
||||||
|
|
||||||
|
return `${url}?${query}&layer=${layer}&format=${format}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rasterSource(tiles, attribution) {
|
||||||
|
return {
|
||||||
|
type: 'raster',
|
||||||
|
tiles,
|
||||||
|
tileSize: 256,
|
||||||
|
attribution,
|
||||||
|
minzoom: 0,
|
||||||
|
maxzoom: 18
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
version: 8,
|
version: 8,
|
||||||
metadat: {
|
metadat: {
|
||||||
'mapbox:autocomposite': false,
|
'mapbox:autocomposite': false,
|
||||||
'mapbox:groups': {
|
'mapbox:groups': {
|
||||||
'1444849242106.713': { collapsed: false, name: 'Places' },
|
1444849242106.713: { collapsed: false, name: 'Places' },
|
||||||
'1444849334699.1902': { collapsed: true, name: 'Bridges' },
|
1444849334699.1902: { collapsed: true, name: 'Bridges' },
|
||||||
'1444849345966.4436': { collapsed: false, name: 'Roads' },
|
1444849345966.4436: { collapsed: false, name: 'Roads' },
|
||||||
'1444849354174.1904': { collapsed: true, name: 'Tunnels' },
|
1444849354174.1904: { collapsed: true, name: 'Tunnels' },
|
||||||
'1444849364238.8171': { collapsed: false, name: 'Buildings' },
|
1444849364238.8171: { collapsed: false, name: 'Buildings' },
|
||||||
'1444849382550.77': { collapsed: false, name: 'Water' },
|
1444849382550.77: { collapsed: false, name: 'Water' },
|
||||||
'1444849388993.3071': { collapsed: false, name: 'Land' }
|
1444849388993.3071: { collapsed: false, name: 'Land' }
|
||||||
},
|
},
|
||||||
'mapbox:type': 'template',
|
'mapbox:type': 'template',
|
||||||
'openmaptiles:mapbox:owner': 'openmaptiles',
|
'openmaptiles:mapbox:owner': 'openmaptiles',
|
||||||
|
@ -41,20 +62,34 @@ export default {
|
||||||
minzoom: 0,
|
minzoom: 0,
|
||||||
maxzoom: 19
|
maxzoom: 19
|
||||||
},
|
},
|
||||||
'carte-ign': {
|
|
||||||
type: 'raster',
|
|
||||||
tiles: [
|
|
||||||
'https://wxs.ign.fr/rc1egnbeoss72hxvd143tbyk/geoportail/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=GEOGRAPHICALGRIDSYSTEMS.MAPS&format=image/jpeg&style=normal'
|
|
||||||
],
|
|
||||||
tileSize: 256,
|
|
||||||
attribution: 'IGN-F/Géoportail',
|
|
||||||
minzoom: 0,
|
|
||||||
maxzoom: 18
|
|
||||||
},
|
|
||||||
cadastre: {
|
cadastre: {
|
||||||
type: 'vector',
|
type: 'vector',
|
||||||
url: 'https://openmaptiles.geo.data.gouv.fr/data/cadastre.json'
|
url: 'https://openmaptiles.geo.data.gouv.fr/data/cadastre.json'
|
||||||
}
|
},
|
||||||
|
'plan-ign': rasterSource(
|
||||||
|
[ignServiceURL('GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2')],
|
||||||
|
'IGN-F/Géoportail'
|
||||||
|
),
|
||||||
|
'protectedareas-gp': rasterSource(
|
||||||
|
[ignServiceURL('PROTECTEDAREAS.GP')],
|
||||||
|
'IGN-F/Géoportail/MNHN'
|
||||||
|
),
|
||||||
|
'protectedareas-pn': rasterSource(
|
||||||
|
[ignServiceURL('PROTECTEDAREAS.PN')],
|
||||||
|
'IGN-F/Géoportail/MNHN'
|
||||||
|
),
|
||||||
|
'protectedareas-pnr': rasterSource(
|
||||||
|
[ignServiceURL('PROTECTEDAREAS.PNR')],
|
||||||
|
'IGN-F/Géoportail/MNHN'
|
||||||
|
),
|
||||||
|
'protectedareas-sic': rasterSource(
|
||||||
|
[ignServiceURL('PROTECTEDAREAS.SIC')],
|
||||||
|
'IGN-F/Géoportail/MNHN'
|
||||||
|
),
|
||||||
|
'protectedareas-zps': rasterSource(
|
||||||
|
[ignServiceURL('PROTECTEDAREAS.ZPS')],
|
||||||
|
'IGN-F/Géoportail/MNHN'
|
||||||
|
)
|
||||||
},
|
},
|
||||||
sprite: 'https://openmaptiles.github.io/osm-bright-gl-style/sprite',
|
sprite: 'https://openmaptiles.github.io/osm-bright-gl-style/sprite',
|
||||||
glyphs: 'https://openmaptiles.geo.data.gouv.fr/fonts/{fontstack}/{range}.pbf'
|
glyphs: 'https://openmaptiles.geo.data.gouv.fr/fonts/{fontstack}/{range}.pbf'
|
||||||
|
|
|
@ -3,16 +3,16 @@ import cadastre from './cadastre';
|
||||||
import orthoStyle from './ortho-style';
|
import orthoStyle from './ortho-style';
|
||||||
import vectorStyle from './vector-style';
|
import vectorStyle from './vector-style';
|
||||||
|
|
||||||
const ignStyle = [
|
function rasterStyle(source) {
|
||||||
{
|
return {
|
||||||
id: 'carte-ign',
|
id: source,
|
||||||
|
source,
|
||||||
type: 'raster',
|
type: 'raster',
|
||||||
source: 'carte-ign',
|
|
||||||
paint: { 'raster-resampling': 'linear' }
|
paint: { 'raster-resampling': 'linear' }
|
||||||
}
|
};
|
||||||
];
|
}
|
||||||
|
|
||||||
export function getMapStyle(style, hasCadastres) {
|
export function getMapStyle(style, hasCadastres, hasMNHN) {
|
||||||
const mapStyle = { ...baseStyle };
|
const mapStyle = { ...baseStyle };
|
||||||
|
|
||||||
switch (style) {
|
switch (style) {
|
||||||
|
@ -27,7 +27,7 @@ export function getMapStyle(style, hasCadastres) {
|
||||||
mapStyle.name = 'Carte OSM';
|
mapStyle.name = 'Carte OSM';
|
||||||
break;
|
break;
|
||||||
case 'ign':
|
case 'ign':
|
||||||
mapStyle.layers = ignStyle;
|
mapStyle.layers = [rasterStyle('plan-ign')];
|
||||||
mapStyle.id = 'ign';
|
mapStyle.id = 'ign';
|
||||||
mapStyle.name = 'Carte IGN';
|
mapStyle.name = 'Carte IGN';
|
||||||
break;
|
break;
|
||||||
|
@ -38,6 +38,17 @@ export function getMapStyle(style, hasCadastres) {
|
||||||
mapStyle.id += '-cadastre';
|
mapStyle.id += '-cadastre';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasMNHN) {
|
||||||
|
mapStyle.layers = mapStyle.layers.concat([
|
||||||
|
rasterStyle('protectedareas-gp'),
|
||||||
|
rasterStyle('protectedareas-pn'),
|
||||||
|
rasterStyle('protectedareas-pnr'),
|
||||||
|
rasterStyle('protectedareas-sic'),
|
||||||
|
rasterStyle('protectedareas-zps')
|
||||||
|
]);
|
||||||
|
mapStyle.id += '-mnhn';
|
||||||
|
}
|
||||||
|
|
||||||
return mapStyle;
|
return mapStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,10 @@ const TypeDeChamp = sortableElement(
|
||||||
label="Cadastres"
|
label="Cadastres"
|
||||||
handler={updateHandlers.cadastres}
|
handler={updateHandlers.cadastres}
|
||||||
/>
|
/>
|
||||||
|
<TypeDeChampCarteOption
|
||||||
|
label="Zones naturelles protégées"
|
||||||
|
handler={updateHandlers.mnhn}
|
||||||
|
/>
|
||||||
</TypeDeChampCarteOptions>
|
</TypeDeChampCarteOptions>
|
||||||
<TypeDeChampRepetitionOptions
|
<TypeDeChampRepetitionOptions
|
||||||
isVisible={isRepetition}
|
isVisible={isRepetition}
|
||||||
|
@ -206,6 +210,7 @@ function createUpdateHandlers(dispatch, typeDeChamp, index, prefix) {
|
||||||
|
|
||||||
export const FIELDS = [
|
export const FIELDS = [
|
||||||
'cadastres',
|
'cadastres',
|
||||||
|
'mnhn',
|
||||||
'description',
|
'description',
|
||||||
'drop_down_list_value',
|
'drop_down_list_value',
|
||||||
'libelle',
|
'libelle',
|
||||||
|
|
|
@ -57,6 +57,18 @@ class Champs::CarteChamp < Champ
|
||||||
type_de_champ&.parcelles_agricoles && type_de_champ.parcelles_agricoles != '0'
|
type_de_champ&.parcelles_agricoles && type_de_champ.parcelles_agricoles != '0'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mnhn?
|
||||||
|
type_de_champ&.mnhn && type_de_champ.mnhn != '0'
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_options
|
||||||
|
{
|
||||||
|
ign: Flipper.enabled?(:carte_ign, procedure),
|
||||||
|
mnhn: mnhn?,
|
||||||
|
cadastres: cadastres?
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def position
|
def position
|
||||||
if dossier.present?
|
if dossier.present?
|
||||||
dossier.geo_position
|
dossier.geo_position
|
||||||
|
|
|
@ -56,7 +56,7 @@ class TypeDeChamp < ApplicationRecord
|
||||||
belongs_to :parent, class_name: 'TypeDeChamp', optional: true
|
belongs_to :parent, class_name: 'TypeDeChamp', optional: true
|
||||||
has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', inverse_of: :parent, dependent: :destroy
|
has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', inverse_of: :parent, dependent: :destroy
|
||||||
|
|
||||||
store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj, :drop_down_options, :skip_pj_validation
|
store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :mnhn, :old_pj, :drop_down_options, :skip_pj_validation
|
||||||
has_many :revision_types_de_champ, class_name: 'ProcedureRevisionTypeDeChamp', dependent: :destroy, inverse_of: :type_de_champ
|
has_many :revision_types_de_champ, class_name: 'ProcedureRevisionTypeDeChamp', dependent: :destroy, inverse_of: :type_de_champ
|
||||||
|
|
||||||
delegate :tags_for_template, to: :dynamic_type
|
delegate :tags_for_template, to: :dynamic_type
|
||||||
|
@ -286,12 +286,11 @@ class TypeDeChamp < ApplicationRecord
|
||||||
:updated_at
|
:updated_at
|
||||||
],
|
],
|
||||||
methods: [
|
methods: [
|
||||||
:cadastres,
|
|
||||||
:drop_down_list_value,
|
:drop_down_list_value,
|
||||||
:parcelles_agricoles,
|
|
||||||
:piece_justificative_template_filename,
|
:piece_justificative_template_filename,
|
||||||
:piece_justificative_template_url,
|
:piece_justificative_template_url,
|
||||||
:quartiers_prioritaires
|
:cadastres,
|
||||||
|
:mnhn
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
TYPES_DE_CHAMP = TYPES_DE_CHAMP_BASE
|
TYPES_DE_CHAMP = TYPES_DE_CHAMP_BASE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
- if champ.geometry?
|
- if champ.geometry?
|
||||||
= react_component("MapReader", { featureCollection: champ.to_feature_collection, ign: feature_enabled_for?(:carte_ign, champ.procedure) } )
|
= react_component("MapReader", { featureCollection: champ.to_feature_collection, options: champ.render_options } )
|
||||||
.geo-areas
|
.geo-areas
|
||||||
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, editing: false }
|
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, editing: false }
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
- preview = !champ.persisted?
|
- preview = !champ.persisted?
|
||||||
= react_component("MapEditor", { featureCollection: champ.to_feature_collection, url: champs_carte_features_path(preview ? 'preview' : champ), preview: preview, hasCadastres: !!champ.cadastres?, ign: feature_enabled_for?(:carte_ign, champ.procedure) }, class: "carte-#{champ.id}")
|
- url = champs_carte_features_path(preview ? 'preview' : champ)
|
||||||
|
= react_component("MapEditor", { featureCollection: champ.to_feature_collection, url: url, preview: preview, options: champ.render_options }, class: "carte-#{champ.id}")
|
||||||
|
|
||||||
.geo-areas
|
.geo-areas
|
||||||
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, editing: true }
|
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, editing: true }
|
||||||
|
|
Loading…
Add table
Reference in a new issue