Estoy haciendo un proyecto de geoposicionamiento con Angular + Openlayers + GeoServer. El caso es que tengo un componente mapa en el menú de inicio que carga perfectamente, pero tengo que añadir un segundo mapa con el que dibujar polígonos en otra pestaña. Este segundo mapa, que es otro componente distinto, aunque comparte parte del código con el otro, no carga cuando accedo a la pestaña, pero una vez estoy en la pestaña y recargo la web si carga el componente. Seguro que es una tontería que se me está pasando, pero no la veo, a ver si me podéis echar una mano.
Lo meto en spoiler porque son +300 líneas de código.
export const DEFAULT_HEIGHT = '100vh';
export const DEFAULT_WIDTH = '100vh';
@Component({
selector: 'app-mapdrawing',
templateUrl: './mapdrawing.component.html',
styleUrls: ['./mapdrawing.component.scss']
})
export class MapdrawingComponent implements OnInit, AfterViewInit {
/* Map parameters. Means lat: latitude, lon: longitude, zoom, width and height */
@Input() lat: number;
@Input() lon: number;
@Input() zoom: number;
@Input() width: string | number = DEFAULT_WIDTH;
@Input() height: string | number = DEFAULT_HEIGHT;
public visible: boolean;
map: Map;
private mapEl: HTMLElement;
constructor(private elementRef: ElementRef, private utilService: UtilsService) { }
ngOnInit(): void {
this.mapEl = this.elementRef.nativeElement.querySelector('#map');
this.setSize();
//addInteraction();
setTimeout(() => {
this.map.updateSize();
console.log(this.map.getView().getCenter())
console.log("prueba")
}, /*map load time*/1500);
}
/* Initialize the map according to longitude and latitude. */
ngAfterViewInit(): void {
this.map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new XYZ({
url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
})
}),
new TileLayer({
source: new TileWMS({
url: '',
params: {
'service': 'WMS&version=1.1.0',
'request': 'GetMap',
'layers': 'GeoStatum:Location',
'bbox': '180.0,-90.0,180.0,90.0',
'width': '100',
'height': '100',
'srs': 'EPSG:4326',
'format': 'image/png; mode=8bit',
'transparent':'true',
'tiled': 'true',
}
})
}),
],
view: new View({
center: Proj.fromLonLat([this.lon, this.lat]),
zoom: this.zoom
}),
controls: defaultControls().extend([])
});
}
/*
*)
/* Adapts the map to the screen size depending of the device*/
private setSize(): void {
if (this.mapEl) {
const styles = this.mapEl.style;
styles.height = coerceCssPixelValue(this.height) || DEFAULT_HEIGHT;
styles.width = coerceCssPixelValue(this.width) || DEFAULT_WIDTH;
}
}
}
const cssUnitsPattern = /([A-Za-z%]+)$/;
function coerceCssPixelValue(value: any): string {
if (value == null) {
return '';
}
return cssUnitsPattern.test(value) ? value : ${value}px
;
}
function length(a,b){
return Math.sqrt(
(b[0]- a[0]) * (b[0] - a[0]) + (b[1] - a[1]) * (b[1] - a[1])
);
}
function isOnSegment(c: any, a: any, b: any) {
var lengthAc = length(a, c);
var lengthAb = length(a, b);
var dot =
((c[0] - a[0]) * (b[0] - a[0]) + (c[1] - a[1]) * (b[1] - a[1])) / lengthAb;
return Math.abs(lengthAc - dot) < 1e-6 && lengthAc < lengthAb;
}
function mod(a: any, b: any) {
return ((a % b) + b) % b;
}
function getPartialRingCoords(feature: any, startPoint: any, endPoint: any){
var polygon = feature.getGeometry();
if (polygon.getType() === 'MultiPolygon'){
polygon = polygon.getPolygon(0);
}
var ringCoords = polygon.getLinearRing().getCoordinates();
var i, pointA, pointB, startSegmentIndex = -1;
for(i = 0; i < ringCoords.length; i++){
pointA = ringCoords;
pointB = ringCoords[mod(i + 1, ringCoords.length)];
// check if this is the start segment dot product
if(isOnSegment(startPoint, pointA, pointB)){
startSegmentIndex = i;
break;
}
}
var cwCoordinates = [];
var cwLength = 0;
var ccwCoordinates = [];
var ccwLength = 0;
// build clockwise coordinates
for (i = 0; i < ringCoords.length; i++){
pointA =
i === 0
? startPoint
: ringCoords[mod(i + startSegmentIndex, ringCoords.length)];
pointB = ringCoords[mod(i + startSegmentIndex + 1, ringCoords.length)];
cwCoordinates.push(pointA);
if (isOnSegment(endPoint, pointA, pointB)) {
cwCoordinates.push(endPoint);
cwLength += length(pointA, endPoint);
break;
} else {
cwLength += length(pointA, pointB);
}
}
// build counter-clockwise coordinates
for (i = 0; i < ringCoords.length; i++){
pointA = ringCoords[mod(startSegmentIndex - i, ringCoords.length)];
pointB =
i === 0
?startPoint
:ringCoords[mod(startSegmentIndex - i + 1, ringCoords.length)];
ccwCoordinates.push(pointB);
if (isOnSegment(endPoint, pointA, pointB)) {
ccwCoordinates.push(endPoint);
ccwLength += length(endPoint, pointB);
break;
} else {
ccwLength += length(pointA, pointB);
}
}
// keep the shortest path
return ccwLength < cwLength ? ccwCoordinates : cwCoordinates;
}
//layers definition
var raster = new TileLayer({
source: new OSM(),
});
// features in this layer will be snapped to
var baseVector = new VectorLayer({
source: new VectorSource({
format: new GeoJSON(),
url:
"https://ahocevar.com/geoserver/wfs?service=wfs&request=getfeature&typename=topp:states&cql_filter=STATE_NAME='Idaho'&outputformat=application/json",
}),
});
// this is were the drawn features go
var drawVector = new VectorLayer({
source: new VectorSource(),
style: new Style({
stroke: new Stroke({
color: 'rgba(100, 255, 0, 1)',
width: 2,
}),
fill: new Fill({
color: 'rgba(100, 255, 0, 0.3)',
}),
}),
});
// this line only appears when we're tracing a feature outer ring
var previewLine = new Feature({
geometry: new LineString([]),
});
var previewVector = new VectorLayer({
source: new VectorSource({
features: [previewLine],
}),
style: new Style({
stroke: new Stroke({
color: 'rgba(255, 0, 0, 1)',
width: 2,
}),
}),
});
var map = new Map({
layers: [raster, baseVector, drawVector, previewVector],
target: 'map',
view: new View({
center: [-12986427, 5678422],
zoom: 5,
}),
});
var drawInteraction, tracingFeature, startPoint, endPoint;
var drawing = false;
var getFeatureOptions = {
hitTolerance: 10,
layerFilter: function (layer) {
return layer === baseVector;
},
};
// the click event is used to start/end tracing around a feature
map.on('click', function (event) {
if (!drawing) {
return;
}
var hit = false;
map.forEachFeatureAtPixel(
event.pixel,
function (feature) {
if (tracingFeature && feature !== tracingFeature) {
return;
}
hit = true;
var coord = map.getCoordinateFromPixel(event.pixel);
// second click on the tracing feature: append the ring coordinates
if (feature === tracingFeature) {
endPoint = tracingFeature.getGeometry().getClosestPoint(coord);
var appendCoords = getPartialRingCoords(
tracingFeature,
startPoint,
endPoint
);
drawInteraction.removeLastPoint();
drawInteraction.appendCoordinates(appendCoords);
tracingFeature = null;
}
// start tracing on the feature ring
tracingFeature = feature;
startPoint = tracingFeature.getGeometry().getClosestPoint(coord);
},
getFeatureOptions
);
if (!hit) {
// clear current tracing feature & preview
//he puesto setProperties porque no pillaba el setCoordinates.
previewLine.getGeometry().setProperties([]);
tracingFeature = null;
}
});
// the pointermove event is used to show a preview of the result of the tracing
map.on('pointermove', function (event) {
if (tracingFeature && drawing) {
var coord = null;
map.forEachFeatureAtPixel(
event.pixel,
function (feature) {
if (tracingFeature === feature) {
coord = map.getCoordinateFromPixel(event.pixel);
}
},
getFeatureOptions
);
var previewCoords = [];
if (coord) {
endPoint = tracingFeature.getGeometry().getClosestPoint(coord);
previewCoords = getPartialRingCoords(
tracingFeature,
startPoint,
endPoint
);
}
previewLine.getGeometry().setProperties(previewCoords);
}
});
var snapInteraction = new Snap({
source: baseVector.getSource(),
});
function addInteraction() {
drawInteraction = new Draw({
source: drawVector.getSource(),
type: GeometryType.POLYGON,
});
drawInteraction.on('drawstart', function () {
drawing = true;
});
drawInteraction.on('drawend', function () {
drawing = false;
previewLine.getGeometry().setProperties([]);
tracingFeature = null;
});
map.addInteraction(drawInteraction);
map.addInteraction(snapInteraction);
};
addInteraction();
html donde debería cargar el mapa.
<mat-toolbar class="expanded-toolbar">
<mat-icon aria-hidden="false" aria-label="Example home icon" routerLink="/home">arrow_back</mat-icon>
<span class="title-center"></span>
<button (click)="Reload()"></button>
</mat-toolbar>
<app-mapdrawing [lat]="" [lon]="" [zoom]="8" width="100%" height="94vh" ></app-mapdrawing>