Skip to content

Conversation

@DongkunXu
Copy link

The new IndoorMapManager class has been added to easily create indoor maps and add them to existing maps. Contains another class "NuclearBuildingManager" which instantiates an IndoorMapManager for loading the indoor map of the nuclear building.

Copy link

@fzampella-huawei fzampella-huawei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good implementation, only add the indoor map to the GoogleMap instance and put the images under a folder named Nucleus, or with a nucleus prefix to be able to extend to other buildings

public class NuclearBuildingManager {
private IndoorMapManager indoorMapManager;

public NuclearBuildingManager(GoogleMap map) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change the name to NucleusBuildingManager

Add an instance of the manager into the StartLocationFragment or RecordingFragment to show the map if the user is inside

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this files (all floors) under a Nucleus folder or with a <building_name>_ prefix

@fzampella-huawei fzampella-huawei linked an issue May 17, 2024 that may be closed by this pull request
// This is just a demonstration of the automatic expansion of the indoor map.
// Assume that we have obtained the user's position "newPosition" from the callback function.
if (newPosition != null) {
if (Nuclear.contains(newPosition)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current version of Google Maps, it appears that the LatLngBounds "contains" method internally does not check to see if an element is actually inside the bounds- it creates a square the size of the bounding box and checks if the point is inside it.
This would not account for differently shaped buildings.

Would it not be better to use a point-in-polygon implemented in my previous PR? @fzampella-huawei

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Ray-Casting Algorithm to determine whether the user is within a polygon to suit irregular buildings.

Copy link

@fzampella-huawei fzampella-huawei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inPolygon detection needs to be fixed before merging. As @Codermaga suggested, and you corrected the ray tracing algorithm is better for non rectangular cases.

Comment on lines 199 to 252

}

/**
* Determines if a given point is inside a polygon.
*
* @param point the point to check
* @param polygon the list of LatLng points representing the vertices of the polygon
* @return true if the point is inside the polygon, false otherwise
*/
private boolean isPointInPolygon(LatLng point, ArrayList<LatLng> polygon) {
int intersectCount = 0;
// Loop through each edge of the polygon
for (int j = 0; j < polygon.size() - 1; j++) {
// Check if the ray from the point intersects with the edge
if (rayCastIntersect(point, polygon.get(j), polygon.get(j + 1))) {
intersectCount++;
}
}
// If the number of intersections is odd, the point is inside the polygon
return ((intersectCount % 2) == 1); // odd = inside, even = outside;
}

/**
* Determines if a ray from a point intersects with a given edge of the polygon.
*
* @param point the point from which the ray is cast
* @param vertA the first vertex of the edge
* @param vertB the second vertex of the edge
* @return true if the ray intersects with the edge, false otherwise
*/
private boolean rayCastIntersect(LatLng point, LatLng vertA, LatLng vertB) {
double aY = vertA.latitude;
double bY = vertB.latitude;
double aX = vertA.longitude;
double bX = vertB.longitude;
double pY = point.latitude;
double pX = point.longitude;

// Check if the point is horizontally aligned with the edge
if ((aY > pY && bY > pY) || (aY < pY && bY < pY) || (aX < pX && bX < pX)) {
return false;
}

// Calculate the slope of the edge
double m = (aY - bY) / (aX - bX);
// Calculate the y-intercept of the edge
double bee = -aX * m + aY;
// Calculate the x-coordinate of the intersection point of the ray and the edge
double x = (pY - bee) / m;

// Return true if the intersection point is to the right of the point
return x > pX;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This functions are available from BuildingPolygon. Make that pointInPolygon function public and add a contain(LatLng point) function to the IndoorMap that uses it. You will need to add the polygon to the IndoorMap as it is created (from the bounds (4 points for a non closed polygon, not 2)

Comment on lines 91 to 93
ArrayList<LatLng> buildingPolygon = new ArrayList<>();
buildingPolygon.add(new LatLng(55.922679, -3.174672));
buildingPolygon.add(new LatLng(55.923316, -3.173781));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The building polygon in this case needs 4 points (assuming it is non closed), not 2. I prefer if the polygon assignment is part of the IndoorMap creation

Copy link

@fzampella-huawei fzampella-huawei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

@fzampella-huawei fzampella-huawei merged commit db67387 into openpositioning:develop May 21, 2024
@Codermaga
Copy link

Codermaga commented May 21, 2024

@fzampella-huawei Isn't there a lot of repetitive code now, the point in polygon is written in BuildingPolygon class(written by me) previously.
In this PR there is pointInPolygon duplicated in NucleusBuildingManager.
(and a lot of redundant code as it does not update my version of the IndoorMapManager class and also the BuildingPolygon class )
The PR instead makes another IndoorMapManager under the subfolder fragment.

The images as well as are duplicated as they are present in the previous PR.

@fzampella-huawei
Copy link

@Codermaga , I know that there some redundant code and I understand your concern, but wanted to integrate the pull request and I will clean the code myself later given the initial deadline for the contributions.

I understand that the previous IndoorMapManager had a similar target, but I liked that this implementation instantiated the buildings, the final version will be a mix between both approaches and will rely on your BuildingPolygon implementation

PhilipHep referenced this pull request in PhilipHep/PositionMe_Fork Feb 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add indoor map information

3 participants