fix: ignore null-island location

Closes #149
This commit is contained in:
Jovan Krunić
2021-10-27 13:44:07 +02:00
parent e29a68bb03
commit d3188f5090
6 changed files with 86 additions and 26 deletions

View File

@@ -12,7 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {Component, Input} from '@angular/core'; import {Component, Input, OnInit} from '@angular/core';
import { import {
SCBuilding, SCBuilding,
SCFloor, SCFloor,
@@ -21,6 +21,7 @@ import {
SCThings, SCThings,
} from '@openstapps/core'; } from '@openstapps/core';
import {DataProvider} from '../../data.provider'; import {DataProvider} from '../../data.provider';
import {hasValidLocation, isSCFloor} from './place-types';
/** /**
* TODO * TODO
@@ -31,12 +32,17 @@ import {DataProvider} from '../../data.provider';
selector: 'stapps-place-detail-content', selector: 'stapps-place-detail-content',
templateUrl: 'place-detail-content.html', templateUrl: 'place-detail-content.html',
}) })
export class PlaceDetailContentComponent { export class PlaceDetailContentComponent implements OnInit {
/** /**
* TODO * TODO
*/ */
@Input() item: SCBuilding | SCRoom | SCPointOfInterest | SCFloor; @Input() item: SCBuilding | SCRoom | SCPointOfInterest | SCFloor;
/**
* Does it have valid location or not (for showing in in a map widget)
*/
hasValidLocation = false;
/** /**
* TODO * TODO
* *
@@ -60,4 +66,9 @@ export class PlaceDetailContentComponent {
(item.categories as string[]).includes('restaurant')) (item.categories as string[]).includes('restaurant'))
); );
} }
ngOnInit() {
this.hasValidLocation =
!isSCFloor(this.item) && hasValidLocation(this.item);
}
} }

View File

@@ -26,8 +26,8 @@
</ion-card-content> </ion-card-content>
</ion-card> </ion-card>
</ng-container> </ng-container>
<ng-container *ngIf="item.type !== 'floor'"> <ng-container *ngIf="hasValidLocation">
<ion-card *ngIf="item.geo" class="map-widget"> <ion-card class="map-widget">
<stapps-map-widget [place]="item" expandable="true"></stapps-map-widget> <stapps-map-widget [place]="item" expandable="true"></stapps-map-widget>
</ion-card> </ion-card>
</ng-container> </ng-container>

View File

@@ -13,22 +13,14 @@
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {Component, Input} from '@angular/core'; import {Component, Input} from '@angular/core';
import {SCBuilding, SCFloor, SCPointOfInterest, SCRoom} from '@openstapps/core';
import {PositionService} from '../../../map/position.service'; import {PositionService} from '../../../map/position.service';
import {Subscription, interval} from 'rxjs'; import {Subscription, interval} from 'rxjs';
import {
type placeTypes = (SCBuilding | SCRoom | SCPointOfInterest | SCFloor) & { hasValidLocation,
distance?: number; isSCFloor,
}; PlaceTypes,
PlaceTypesWithDistance,
/** } from './place-types';
* 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';
}
/** /**
* Shows a place as a list item * Shows a place as a list item
@@ -41,16 +33,16 @@ export class PlaceListItemComponent {
/** /**
* Item getter * Item getter
*/ */
get item(): placeTypes { get item(): PlaceTypesWithDistance {
return this._item; return this._item;
} }
/** /**
* An item to show (setter is used as there were issues assigning the distance to the right place in a list) * 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; this._item = item;
if (!isSCFloor(item)) { if (!isSCFloor(item) && hasValidLocation(item)) {
this.distance = this.positionService.getDistance(item.geo.point); this.distance = this.positionService.getDistance(item.geo.point);
this.distanceSubscription = interval(10_000).subscribe(_ => { this.distanceSubscription = interval(10_000).subscribe(_ => {
this.distance = this.positionService.getDistance(item.geo.point); this.distance = this.positionService.getDistance(item.geo.point);
@@ -61,7 +53,7 @@ export class PlaceListItemComponent {
/** /**
* An item to show * An item to show
*/ */
private _item: placeTypes; private _item: PlaceTypesWithDistance;
/** /**
* Distance in meters * Distance in meters

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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<PlaceTypes, SCFloor>) {
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';
}

View File

@@ -14,6 +14,7 @@
*/ */
import {ElementRef, Injectable} from '@angular/core'; import {ElementRef, Injectable} from '@angular/core';
import { import {
SCBuilding,
SCSearchFilter, SCSearchFilter,
SCSearchQuery, SCSearchQuery,
SCSearchResponse, SCSearchResponse,
@@ -24,6 +25,7 @@ import {Point, Polygon} from 'geojson';
import {divIcon, geoJSON, icon, LatLng, Map, marker, Marker} from 'leaflet'; import {divIcon, geoJSON, icon, LatLng, Map, marker, Marker} from 'leaflet';
import {DataProvider} from '../data/data.provider'; import {DataProvider} from '../data/data.provider';
import {MapPosition, PositionService} from './position.service'; import {MapPosition, PositionService} from './position.service';
import {hasValidLocation} from '../data/types/place/place-types';
/** /**
* Provides methods for presenting the map * 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 contextFilter Additional contextual filter (e.g. from the context menu)
* @param queryText Query (text) of the search query * @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;
} }
} }

View File

@@ -448,12 +448,15 @@ export class MapPageComponent {
* Show a single place * Show a single place
*/ */
async showItemModal(item: SCPlace) { async showItemModal(item: SCPlace) {
const placeWithoutGeo = {...item, geo: undefined}; const placeWithNullLocation = {
...item,
geo: {point: {coordinates: [0, 0]}},
};
this.modal = await this.modalController.create({ this.modal = await this.modalController.create({
component: MapSingleModalComponent, component: MapSingleModalComponent,
swipeToClose: true, swipeToClose: true,
componentProps: { componentProps: {
item: placeWithoutGeo, item: placeWithNullLocation,
dismissAction: () => { dismissAction: () => {
this.modal.dismiss(); this.modal.dismiss();
}, },