Skip to content

Commit

Permalink
task/WG-83: Handle Overlapping Point Clouds (#181)
Browse files Browse the repository at this point in the history
* task/WG-83: Handle Overlapping Point Clouds

* Fixing linting issues

* Removing redundant code for adding feature

---------

Co-authored-by: Taylor Grafft <[email protected]>
  • Loading branch information
tjgrafft and Taylor Grafft authored Dec 18, 2023
1 parent 58f7724 commit 6a34d5f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 12 deletions.
33 changes: 25 additions & 8 deletions angular/src/app/components/map/map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import '@bagage/leaflet.vectorgrid';
import { Viewer, ViewerOptions } from 'mapillary-js';
import { ProjectsService } from '../../services/projects.service';
import { GeoDataService } from '../../services/geo-data.service';
import { createMarker } from '../../utils/leafletUtils';
import { createMarker, calculateMarkerPosition } from '../../utils/leafletUtils';
import { Feature } from 'geojson';
import { FeatureGroup, Layer, LayerGroup, LeafletMouseEvent, TileLayer } from 'leaflet';
import * as turf from '@turf/turf';
Expand Down Expand Up @@ -350,6 +350,14 @@ export class MapComponent implements OnInit, OnDestroy {
let feat: LayerGroup;
if (d.geometry.type === 'Polygon' && d.properties.style) {
feat = L.geoJSON(d, { style: d.properties.style });
} else if (d.featureType() === 'point_cloud') {
feat = L.geoJSON(d, { style: d.properties.style });
const markerPosition = calculateMarkerPosition(d.geometry);
const pointCloudMarker = createMarker(d, markerPosition);
pointCloudMarker.on('click', (ev) => {
this.featureClickHandler(ev, 'click');
});
markers.addLayer(pointCloudMarker);
} else if (d.featureType() === 'streetview') {
feat = L.geoJSON(d, {
style: streetviewAssetStyles.feature.default,
Expand Down Expand Up @@ -398,13 +406,22 @@ export class MapComponent implements OnInit, OnDestroy {
}

featureClickHandler(ev: any, clickType: string): void {
if (ev.layer.feature.featureType() === 'streetview') {
this.streetviewService.sequenceFeatureToActiveAsset(ev.layer.feature).subscribe((e) => {
this.mapillaryClickHandler(e, clickType);
});
} else {
const f = ev.layer.feature;
this.geoDataService.activeFeature = f;
let f;
// First checks if clicked object is a marker
if (ev.target && ev.target.options.feature) {
f = ev.target.options.feature;
// Otherwise checks if a geoJSON layer with a feature prop
} else if (ev.layer && ev.layer.feature) {
f = ev.layer.feature;
}
if (f) {
if (f.featureType() === 'streetview') {
this.streetviewService.sequenceFeatureToActiveAsset(f).subscribe((e) => {
this.mapillaryClickHandler(e, clickType);
});
} else {
this.geoDataService.activeFeature = f;
}
}
}

Expand Down
39 changes: 35 additions & 4 deletions angular/src/app/utils/leafletUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CircleMarker, Path, circleMarker, divIcon, LatLng, Marker, marker } from 'leaflet';
import { CircleMarker, Path, circleMarker, divIcon, LatLng, Marker, MarkerOptions, marker, icon, geoJSON } from 'leaflet';
import { Feature } from '../models/models';
import { MarkerStyle } from '../models/style';

Expand All @@ -7,6 +7,13 @@ interface MarkerIcon {
name: string;
}

// Needed to add feature to marker options (for click events)
declare module 'leaflet' {
interface MarkerOptions {
feature?: Feature;
}
}

function createCircleMarker(feature: Feature, latlng: LatLng): CircleMarker {
const options = {
radius: 8,
Expand Down Expand Up @@ -38,9 +45,9 @@ function createVideoMarker(feature: Feature, latlng: LatLng): Marker {
}

function createCustomIconMarker(latlng: LatLng, style: MarkerStyle): Marker {
const icon = style.faIcon;
const faIcon = style.faIcon;
const color = style.color;
const divHtml = `<i class="fas ${icon} fa-2x" style="color: ${color}"></i>`;
const divHtml = `<i class="fas ${faIcon} fa-2x" style="color: ${color}"></i>`;
const ico = divIcon({ className: 'leaflet-fa-marker-icon', html: divHtml });
return marker(latlng, { icon: ico, ...style });
}
Expand All @@ -55,8 +62,32 @@ function createCustomCircleMarker(latlng: LatLng, style: MarkerStyle): CircleMar
return circleMarker(latlng, style);
}

function createPointCloudMarker(feature: Feature, latlng: LatLng): Marker {
const divHtml = '<i class="fab fa-mixcloud fa-2x light-blue"></i>';
const customIcon = divIcon({
className: 'leaflet-fa-marker-icon',
html: divHtml,
iconSize: [32, 32],
iconAnchor: [16, 16],
});
// Adding feature data to options prop of marker to statisfy TS type errors
return marker(latlng, {
icon: customIcon,
feature, // shorthand
});
}

// Used to find the top-left corner of our point-clouds to help with overlapping
export function calculateMarkerPosition(geoJsonPolygon): LatLng {
const layer = geoJSON(geoJsonPolygon); // Convert GeoJSON Polygon to Leaflet Layer
const bounds = layer.getBounds();
return new LatLng(bounds.getNorth(), bounds.getWest()); // Top-left corner
}

export function createMarker(feature: Feature, latlng: LatLng): Marker | CircleMarker {
if (feature.properties.style) {
if (feature.featureType() === 'point_cloud') {
return createPointCloudMarker(feature, latlng);
} else if (feature.properties.style) {
const style = feature.properties.style;
if (style.faIcon) {
return createCustomIconMarker(latlng, style);
Expand Down

0 comments on commit 6a34d5f

Please sign in to comment.