From d3188f50905d610097de6c90bc58e6373d30e0dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jovan=20Kruni=C4=87?= Date: Wed, 27 Oct 2021 13:44:07 +0200 Subject: [PATCH] fix: ignore null-island location Closes #149 --- .../place/place-detail-content.component.ts | 15 ++++++- .../types/place/place-detail-content.html | 4 +- .../types/place/place-list-item.component.ts | 28 +++++------- .../modules/data/types/place/place-types.ts | 45 +++++++++++++++++++ src/app/modules/map/map.provider.ts | 13 +++++- .../modules/map/page/map-page.component.ts | 7 ++- 6 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 src/app/modules/data/types/place/place-types.ts diff --git a/src/app/modules/data/types/place/place-detail-content.component.ts b/src/app/modules/data/types/place/place-detail-content.component.ts index 2ff45f4a..6ffa1e62 100644 --- a/src/app/modules/data/types/place/place-detail-content.component.ts +++ b/src/app/modules/data/types/place/place-detail-content.component.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Component, Input} from '@angular/core'; +import {Component, Input, OnInit} from '@angular/core'; import { SCBuilding, SCFloor, @@ -21,6 +21,7 @@ import { SCThings, } from '@openstapps/core'; import {DataProvider} from '../../data.provider'; +import {hasValidLocation, isSCFloor} from './place-types'; /** * TODO @@ -31,12 +32,17 @@ import {DataProvider} from '../../data.provider'; selector: 'stapps-place-detail-content', templateUrl: 'place-detail-content.html', }) -export class PlaceDetailContentComponent { +export class PlaceDetailContentComponent implements OnInit { /** * TODO */ @Input() item: SCBuilding | SCRoom | SCPointOfInterest | SCFloor; + /** + * Does it have valid location or not (for showing in in a map widget) + */ + hasValidLocation = false; + /** * TODO * @@ -60,4 +66,9 @@ export class PlaceDetailContentComponent { (item.categories as string[]).includes('restaurant')) ); } + + ngOnInit() { + this.hasValidLocation = + !isSCFloor(this.item) && hasValidLocation(this.item); + } } diff --git a/src/app/modules/data/types/place/place-detail-content.html b/src/app/modules/data/types/place/place-detail-content.html index 65fe3ceb..0f676725 100644 --- a/src/app/modules/data/types/place/place-detail-content.html +++ b/src/app/modules/data/types/place/place-detail-content.html @@ -26,8 +26,8 @@ - - + + diff --git a/src/app/modules/data/types/place/place-list-item.component.ts b/src/app/modules/data/types/place/place-list-item.component.ts index d640ced5..b636f477 100644 --- a/src/app/modules/data/types/place/place-list-item.component.ts +++ b/src/app/modules/data/types/place/place-list-item.component.ts @@ -13,22 +13,14 @@ * this program. If not, see . */ import {Component, Input} from '@angular/core'; -import {SCBuilding, SCFloor, SCPointOfInterest, SCRoom} from '@openstapps/core'; import {PositionService} from '../../../map/position.service'; import {Subscription, interval} from 'rxjs'; - -type placeTypes = (SCBuilding | SCRoom | SCPointOfInterest | SCFloor) & { - distance?: number; -}; - -/** - * Provide information if a place is a floor - * - * @param place A place to check - */ -function isSCFloor(place: placeTypes): place is SCFloor { - return place.type === 'floor'; -} +import { + hasValidLocation, + isSCFloor, + PlaceTypes, + PlaceTypesWithDistance, +} from './place-types'; /** * Shows a place as a list item @@ -41,16 +33,16 @@ export class PlaceListItemComponent { /** * Item getter */ - get item(): placeTypes { + get item(): PlaceTypesWithDistance { return this._item; } /** * An item to show (setter is used as there were issues assigning the distance to the right place in a list) */ - @Input() set item(item: placeTypes) { + @Input() set item(item: PlaceTypes) { this._item = item; - if (!isSCFloor(item)) { + if (!isSCFloor(item) && hasValidLocation(item)) { this.distance = this.positionService.getDistance(item.geo.point); this.distanceSubscription = interval(10_000).subscribe(_ => { this.distance = this.positionService.getDistance(item.geo.point); @@ -61,7 +53,7 @@ export class PlaceListItemComponent { /** * An item to show */ - private _item: placeTypes; + private _item: PlaceTypesWithDistance; /** * Distance in meters diff --git a/src/app/modules/data/types/place/place-types.ts b/src/app/modules/data/types/place/place-types.ts new file mode 100644 index 00000000..d2cb1d30 --- /dev/null +++ b/src/app/modules/data/types/place/place-types.ts @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2021 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +import {SCBuilding, SCFloor, SCPointOfInterest, SCRoom} from '@openstapps/core'; + +/** + * Possible place types + */ +export type PlaceTypes = SCBuilding | SCRoom | SCPointOfInterest | SCFloor; + +/** + * Place types with their dynamic distance (from the position of the device) + */ +export type PlaceTypesWithDistance = PlaceTypes & { + distance?: number; +}; + +/** + * Detects "null island" places, which means places with point coordinates [0, 0] + * + * @param place A place to check + */ +export function hasValidLocation(place: Exclude) { + return place.geo.point.coordinates.some(coordinate => coordinate !== 0); +} + +/** + * Provide information if a place is a floor + * + * @param place A place to check + */ +export function isSCFloor(place: PlaceTypes): place is SCFloor { + return place.type === 'floor'; +} diff --git a/src/app/modules/map/map.provider.ts b/src/app/modules/map/map.provider.ts index adb70c29..8737d617 100644 --- a/src/app/modules/map/map.provider.ts +++ b/src/app/modules/map/map.provider.ts @@ -14,6 +14,7 @@ */ import {ElementRef, Injectable} from '@angular/core'; import { + SCBuilding, SCSearchFilter, SCSearchQuery, SCSearchResponse, @@ -24,6 +25,7 @@ import {Point, Polygon} from 'geojson'; import {divIcon, geoJSON, icon, LatLng, Map, marker, Marker} from 'leaflet'; import {DataProvider} from '../data/data.provider'; import {MapPosition, PositionService} from './position.service'; +import {hasValidLocation} from '../data/types/place/place-types'; /** * Provides methods for presenting the map @@ -125,7 +127,8 @@ export class MapProvider { } /** - * Provide places (buildings and canteens) + * Provide places (buildings and canteens) const result = await this.dataProvider.search(query); + * * @param contextFilter Additional contextual filter (e.g. from the context menu) * @param queryText Query (text) of the search query @@ -224,6 +227,12 @@ export class MapProvider { ]; } - return this.dataProvider.search(query); + const result = await this.dataProvider.search(query); + + result.data = result.data.filter(place => + hasValidLocation(place as SCBuilding), + ); + + return result; } } diff --git a/src/app/modules/map/page/map-page.component.ts b/src/app/modules/map/page/map-page.component.ts index c2a0e376..967b4992 100644 --- a/src/app/modules/map/page/map-page.component.ts +++ b/src/app/modules/map/page/map-page.component.ts @@ -448,12 +448,15 @@ export class MapPageComponent { * Show a single place */ async showItemModal(item: SCPlace) { - const placeWithoutGeo = {...item, geo: undefined}; + const placeWithNullLocation = { + ...item, + geo: {point: {coordinates: [0, 0]}}, + }; this.modal = await this.modalController.create({ component: MapSingleModalComponent, swipeToClose: true, componentProps: { - item: placeWithoutGeo, + item: placeWithNullLocation, dismissAction: () => { this.modal.dismiss(); },