Version 0.3.2 Alpha¶
Release Date: July 30, 2024
Status: Alpha Release
Build Number: 0.3.2
Overview¶
Version 0.3.2 represents a major milestone in the MINE - Indoor Navigation Engine journey, introducing advanced path finding capabilities that enable real-time route calculation and turn-by-turn navigation within indoor spaces. This release transforms MINE from a map visualization tool into a complete navigation solution.
Stable Alpha Release
This is our most stable alpha release yet, with significant performance improvements and zero critical known issues. Ready for pilot deployments and extensive testing.
Highlights¶
-
Path Finding Engine
Advanced A* algorithm with obstacle avoidance and multi-floor support
-
Performance Optimized
Lightning-fast route calculation with minimal resource consumption
-
Navigation UI
Complete set of UI components for turn-by-turn navigation
-
Extensible System
Plugin architecture for custom routing algorithms
New Features¶
Path Finding Utilities¶
A comprehensive suite of utilities for route calculation, manipulation, and optimization.
Core Capabilities:
- ๐ฏ A* Algorithm Implementation - Efficient shortest path calculation
- ๐ง Obstacle Detection - Automatic avoidance of blocked areas
- ๐ข Multi-Floor Routing - Seamless navigation across building levels
- โฟ Accessible Routes - Alternative paths for accessibility needs
- ๐ Dynamic Rerouting - Real-time route adjustments
- ๐ Distance Calculation - Accurate distance and time estimates
- ๐จ Route Visualization - Beautiful animated path rendering
Usage Example:
import com.machinestalk.indoornavigationengine.util.PathFindingUtil
import com.machinestalk.indoornavigationengine.models.Location
import com.machinestalk.indoornavigationengine.models.Route
class NavigationController(private val sceneView: MineSceneView) {
private val pathFinder = PathFindingUtil(sceneView)
fun calculateRoute(
startLocation: Location,
destinationLocation: Location,
options: RouteOptions = RouteOptions()
): Route? {
return pathFinder.findPath(
start = startLocation,
end = destinationLocation,
options = options
)
}
fun calculateAccessibleRoute(
start: Location,
destination: Location
): Route? {
return pathFinder.findPath(
start = start,
end = destination,
options = RouteOptions(
accessibleOnly = true,
avoidStairs = true,
preferElevators = true
)
)
}
fun getRouteDistance(route: Route): Float {
return pathFinder.calculateDistance(route)
}
fun getEstimatedTime(route: Route, walkingSpeed: Float = 1.4f): Int {
val distance = getRouteDistance(route)
return (distance / walkingSpeed).toInt() // seconds
}
}
import com.machinestalk.indoornavigationengine.util.PathFindingUtil;
import com.machinestalk.indoornavigationengine.models.Location;
import com.machinestalk.indoornavigationengine.models.Route;
import com.machinestalk.indoornavigationengine.models.RouteOptions;
public class NavigationController {
private PathFindingUtil pathFinder;
public NavigationController(MineSceneView sceneView) {
this.pathFinder = new PathFindingUtil(sceneView);
}
public Route calculateRoute(
Location start,
Location destination,
RouteOptions options
) {
return pathFinder.findPath(start, destination, options);
}
public Route calculateAccessibleRoute(Location start, Location destination) {
RouteOptions options = new RouteOptions.Builder()
.setAccessibleOnly(true)
.setAvoidStairs(true)
.setPreferElevators(true)
.build();
return pathFinder.findPath(start, destination, options);
}
public float getRouteDistance(Route route) {
return pathFinder.calculateDistance(route);
}
public int getEstimatedTime(Route route, float walkingSpeed) {
float distance = getRouteDistance(route);
return (int) (distance / walkingSpeed); // seconds
}
}
Route Options:
| Option | Type | Default | Description |
|---|---|---|---|
accessibleOnly |
Boolean | false |
Use only wheelchair-accessible paths |
avoidStairs |
Boolean | false |
Prefer ramps and elevators |
preferElevators |
Boolean | false |
Prioritize elevators over escalators |
maxDistance |
Float | null |
Maximum acceptable route distance |
avoidAreas |
List | [] |
Areas to avoid in routing |
Path Finding Algorithm¶
State-of-the-art A* implementation optimized for indoor navigation with enhanced heuristics.
Algorithm Features:
- ๐งฎ Optimized A* Search - Efficient node exploration with intelligent heuristics
- ๐ฏ Multi-Goal Support - Find paths to multiple destinations simultaneously
- ๐ Bidirectional Search - Faster calculation for long-distance routes
- ๐ Cost Functions - Customizable weighting for different path preferences
- ๐ณ Graph Optimization - Pre-computed navigation meshes for performance
- ๐พ Route Caching - Smart caching of frequently used routes
Technical Implementation:
import com.machinestalk.indoornavigationengine.pathfinding.PathFindingAlgorithm
import com.machinestalk.indoornavigationengine.pathfinding.AStarConfig
// Configure the A* algorithm
val algorithmConfig = AStarConfig(
// Heuristic weight (higher = faster but less accurate)
heuristicWeight = 1.2f,
// Maximum nodes to explore (prevents infinite loops)
maxNodesExplored = 10000,
// Enable diagonal movement
allowDiagonalMovement = true,
// Cost for diagonal moves (typically sqrt(2) โ 1.414)
diagonalCost = 1.414f,
// Enable path smoothing for more natural routes
enablePathSmoothing = true,
// Timeout in milliseconds
timeout = 5000
)
val algorithm = PathFindingAlgorithm.AStar(algorithmConfig)
// Use custom cost function
algorithm.setCostFunction { from, to ->
val baseCost = calculateDistance(from, to)
// Add extra cost for stairs (discourage stair use)
val stairPenalty = if (to.type == NodeType.STAIRS) 2.0f else 0f
// Prefer well-lit areas (reduce cost)
val lightingBonus = if (to.lighting > 0.7f) -0.5f else 0f
baseCost + stairPenalty + lightingBonus
}
// Find path using the configured algorithm
val path = algorithm.findPath(
startNode = startLocation.toNode(),
endNode = destinationLocation.toNode(),
navigationGraph = sceneView.getNavigationGraph()
)
import com.machinestalk.indoornavigationengine.pathfinding.PathFindingAlgorithm;
import com.machinestalk.indoornavigationengine.pathfinding.AStarConfig;
// Configure the A* algorithm
AStarConfig config = new AStarConfig.Builder()
.setHeuristicWeight(1.2f)
.setMaxNodesExplored(10000)
.setAllowDiagonalMovement(true)
.setDiagonalCost(1.414f)
.setEnablePathSmoothing(true)
.setTimeout(5000)
.build();
PathFindingAlgorithm algorithm = PathFindingAlgorithm.createAStar(config);
// Use custom cost function
algorithm.setCostFunction((from, to) -> {
float baseCost = calculateDistance(from, to);
float stairPenalty = to.getType() == NodeType.STAIRS ? 2.0f : 0f;
float lightingBonus = to.getLighting() > 0.7f ? -0.5f : 0f;
return baseCost + stairPenalty + lightingBonus;
});
// Find path
Path path = algorithm.findPath(
startLocation.toNode(),
destinationLocation.toNode(),
sceneView.getNavigationGraph()
);
Performance Benchmarks:
| Scenario | Distance | Nodes | Time | Memory |
|---|---|---|---|---|
| Same floor, short | 20m | 45 | 8ms | 2KB |
| Same floor, long | 150m | 320 | 35ms | 12KB |
| Multi-floor | 200m | 580 | 65ms | 25KB |
| Complex maze | 100m | 1200 | 120ms | 45KB |
Path Finding UI Components¶
Complete set of pre-built UI components for displaying navigation instructions and route information.
Available Components:
Navigation Instruction Panel¶
import com.machinestalk.indoornavigationengine.ui.NavigationInstructionPanel
val instructionPanel = NavigationInstructionPanel(this).apply {
// Configure appearance
setPosition(NavigationInstructionPanel.Position.TOP_CENTER)
setBackgroundColor(Color.parseColor("#2196F3"))
setTextColor(Color.WHITE)
// Set instruction
showInstruction(
action = NavigationAction.TURN_LEFT,
distance = 25f,
description = "Turn left at the food court"
)
// Show next instruction preview
showNextInstruction(
action = NavigationAction.GO_STRAIGHT,
distance = 50f
)
// Handle instruction tap
setOnInstructionClickListener {
// Show detailed instructions
showDetailedDirections()
}
}
sceneView.addUIComponent(instructionPanel)
Route Progress Bar¶
import com.machinestalk.indoornavigationengine.ui.RouteProgressBar
val progressBar = RouteProgressBar(this).apply {
setPosition(RouteProgressBar.Position.BOTTOM)
// Set route information
setTotalDistance(250f) // meters
setRemainingDistance(180f)
setEstimatedTime(180) // seconds
// Customize appearance
setProgressColor(Color.parseColor("#4CAF50"))
setBackgroundColor(Color.parseColor("#E0E0E0"))
setHeight(8.dp)
// Enable auto-update
enableAutoUpdate = true
}
sceneView.addUIComponent(progressBar)
Route Preview Card¶
import com.machinestalk.indoornavigationengine.ui.RoutePreviewCard
val routeCard = RoutePreviewCard(this).apply {
// Set route details
setDestination("Coffee Shop - Floor 2")
setDistance(185f)
setEstimatedTime(135) // seconds
setFloorChanges(1)
// Show route alternatives
addAlternativeRoute(
name = "Shorter route",
distance = 165f,
time = 120,
note = "Via stairs"
)
addAlternativeRoute(
name = "Accessible route",
distance = 210f,
time = 155,
note = "Elevator access"
)
// Handle route selection
setOnRouteSelectedListener { routeIndex ->
startNavigation(routes[routeIndex])
}
}
sceneView.addUIComponent(routeCard)
Turn-by-Turn Direction List¶
import com.machinestalk.indoornavigationengine.ui.DirectionListView
val directionList = DirectionListView(this).apply {
// Add directions from route
route.instructions.forEach { instruction ->
addDirection(
icon = getInstructionIcon(instruction.action),
text = instruction.description,
distance = instruction.distance
)
}
// Highlight current instruction
setCurrentStep(0)
// Handle step selection
setOnStepSelectedListener { stepIndex ->
// Preview this step on map
previewStep(route.instructions[stepIndex])
}
}
// Show in bottom sheet
showBottomSheet(directionList)
UI Component Customization:
// Global UI configuration for all navigation components
NavigationUIConfig.apply {
// Colors
primaryColor = Color.parseColor("#2196F3")
accentColor = Color.parseColor("#FF5722")
textColor = Color.parseColor("#212121")
// Typography
fontFamily = ResourcesCompat.getFont(context, R.font.custom_font)
titleTextSize = 18.sp
bodyTextSize = 14.sp
// Spacing
defaultPadding = 16.dp
componentMargin = 8.dp
// Animations
animationDuration = 300
enableTransitions = true
}
Custom Path Finding Algorithms¶
Extend the navigation engine with your own routing algorithms for specialized use cases.
Plugin Architecture:
import com.machinestalk.indoornavigationengine.pathfinding.CustomPathFinder
import com.machinestalk.indoornavigationengine.pathfinding.PathFinderPlugin
// Create custom algorithm
class ShortestTimePathFinder : PathFinderPlugin {
override val name = "Shortest Time Algorithm"
override val version = "1.0.0"
override fun findPath(
start: Node,
end: Node,
graph: NavigationGraph,
options: RouteOptions
): Path? {
// Implement custom logic
// This example prioritizes faster routes over shorter distances
val openSet = PriorityQueue<Node>(compareBy { it.estimatedTime })
val closedSet = mutableSetOf<Node>()
openSet.add(start)
while (openSet.isNotEmpty()) {
val current = openSet.poll()
if (current == end) {
return reconstructPath(current)
}
closedSet.add(current)
graph.getNeighbors(current).forEach { neighbor ->
if (neighbor in closedSet) return@forEach
val travelTime = calculateTravelTime(current, neighbor)
val newTime = current.totalTime + travelTime
if (newTime < neighbor.totalTime) {
neighbor.totalTime = newTime
neighbor.parent = current
if (neighbor !in openSet) {
openSet.add(neighbor)
}
}
}
}
return null // No path found
}
private fun calculateTravelTime(from: Node, to: Node): Float {
val distance = from.distanceTo(to)
// Different speeds for different path types
val speed = when (to.type) {
NodeType.WALKWAY -> 1.4f // m/s
NodeType.STAIRS -> 0.6f
NodeType.ESCALATOR -> 0.8f
NodeType.ELEVATOR -> 0.5f // includes wait time
else -> 1.0f
}
return distance / speed
}
}
// Register custom algorithm
val customAlgorithm = ShortestTimePathFinder()
PathFindingUtil.registerAlgorithm(customAlgorithm)
// Use custom algorithm
val route = pathFinder.findPath(
start = startLocation,
end = destinationLocation,
algorithm = customAlgorithm
)
import com.machinestalk.indoornavigationengine.pathfinding.PathFinderPlugin;
public class ShortestTimePathFinder implements PathFinderPlugin {
@Override
public String getName() {
return "Shortest Time Algorithm";
}
@Override
public String getVersion() {
return "1.0.0";
}
@Override
public Path findPath(
Node start,
Node end,
NavigationGraph graph,
RouteOptions options
) {
// Custom implementation
PriorityQueue<Node> openSet = new PriorityQueue<>(
Comparator.comparing(Node::getEstimatedTime)
);
Set<Node> closedSet = new HashSet<>();
openSet.add(start);
while (!openSet.isEmpty()) {
Node current = openSet.poll();
if (current.equals(end)) {
return reconstructPath(current);
}
closedSet.add(current);
for (Node neighbor : graph.getNeighbors(current)) {
if (closedSet.contains(neighbor)) continue;
float travelTime = calculateTravelTime(current, neighbor);
float newTime = current.getTotalTime() + travelTime;
if (newTime < neighbor.getTotalTime()) {
neighbor.setTotalTime(newTime);
neighbor.setParent(current);
if (!openSet.contains(neighbor)) {
openSet.add(neighbor);
}
}
}
}
return null;
}
}
Algorithm Selection:
// List available algorithms
val algorithms = PathFindingUtil.getAvailableAlgorithms()
algorithms.forEach { algorithm ->
println("${algorithm.name} v${algorithm.version}")
}
// Use specific algorithm
val route = pathFinder.findPath(
start = startLocation,
end = destinationLocation,
algorithmName = "Shortest Time Algorithm"
)
Performance Optimizations¶
Significant improvements in path calculation speed and resource utilization.
Optimization Techniques:
-
Navigation Graph Preprocessing
// Pre-compute navigation graph for faster queries sceneView.preprocessNavigationGraph( granularity = GraphGranularity.HIGH, includeAccessibilityInfo = true ) -
Route Caching
// Enable intelligent route caching PathFindingUtil.enableCaching( maxCacheSize = 100, ttl = 3600 // seconds ) -
Incremental Updates
// Update only affected portions of the graph navigationGraph.updateRegion( bounds = changedArea, incremental = true )
Performance Improvements:
| Metric | v0.2.1 | v0.3.2 | Improvement |
|---|---|---|---|
| Route Calculation | 180ms | 65ms | โฌ๏ธ 64% |
| Memory Usage | 45MB | 28MB | โฌ๏ธ 38% |
| Graph Loading | 2.1s | 0.8s | โฌ๏ธ 62% |
| Cache Hit Rate | N/A | 78% | โฌ๏ธ New |
| CPU Usage | 35% | 18% | โฌ๏ธ 49% |
Bug Fixes¶
Path Finding Algorithm Stability¶
Issue: The initial path finding implementation had reliability issues: - Occasional crashes when calculating routes on complex maps - Infinite loops in certain edge cases with circular layouts - Memory leaks during long-running navigation sessions - Incorrect routes when dealing with disconnected graph regions
Root Cause: - Insufficient validation of graph connectivity - Missing termination conditions in path search - Improper cleanup of temporary path finding data structures - Edge cases in multi-floor transition handling
Resolution:
// Added comprehensive graph validation
fun validateNavigationGraph(graph: NavigationGraph): ValidationResult {
val issues = mutableListOf<String>()
// Check connectivity
if (!graph.isFullyConnected()) {
issues.add("Graph contains disconnected regions")
}
// Validate nodes
graph.nodes.forEach { node ->
if (node.neighbors.isEmpty() && node.type != NodeType.DESTINATION) {
issues.add("Isolated node detected: ${node.id}")
}
}
// Check for invalid edges
graph.edges.forEach { edge ->
if (edge.cost < 0) {
issues.add("Negative edge cost: ${edge.id}")
}
}
return if (issues.isEmpty()) {
ValidationResult.Valid
} else {
ValidationResult.Invalid(issues)
}
}
// Added safety limits
val pathResult = pathFinder.findPath(
start = start,
end = end,
config = AStarConfig(
maxNodesExplored = 10000, // Prevents infinite loops
timeout = 5000, // 5 second timeout
enableSafetyChecks = true
)
)
Impact: - 99.8% success rate for path calculations (up from 94%) - Zero crashes related to path finding in testing - Memory usage reduced by 38%
Path Finding UI Display Issues¶
Issue: Navigation UI components had several display problems: - Instruction panel text occasionally cut off on small screens - Route progress bar not updating in real-time - Direction icons not loading correctly - Flickering during route updates
Resolution: - Implemented responsive text sizing based on available space - Added real-time location tracking integration for progress updates - Pre-loaded and cached navigation icons - Optimized rendering pipeline to eliminate flickering
Before:
// UI updates caused visual glitches
instructionPanel.updateInstruction(newInstruction)
progressBar.setProgress(newProgress)
// Screen would flicker during updates
After:
// Batch updates for smooth transitions
sceneView.batchUIUpdate {
instructionPanel.updateInstruction(newInstruction)
progressBar.setProgress(newProgress)
// Updates applied atomically with animations
}
Technical Improvements: - Reduced UI update latency by 75% - Eliminated flickering through double-buffering - Improved text rendering with dynamic sizing - Added smooth animation transitions
JSON Parsing for Path Finding Configuration¶
Issue: Parser failed when path finding configuration JSON was empty or malformed, causing: - Application crashes during map initialization - Silent failures without error messages - Incorrect default values being used - Null pointer exceptions
Resolution:
// Robust JSON parsing with fallbacks
fun loadPathFindingConfig(fileName: String): PathFindingConfig {
return try {
val json = JsonUtil.LoadJsonFromAsset(context, fileName)
if (json.isNullOrEmpty()) {
Log.w("PathFinding", "Empty config file, using defaults")
return PathFindingConfig.createDefault()
}
val config = parsePathFindingConfig(json)
// Validate parsed config
if (!config.isValid()) {
Log.w("PathFinding", "Invalid config, using defaults")
return PathFindingConfig.createDefault()
}
config
} catch (e: JsonSyntaxException) {
Log.e("PathFinding", "JSON syntax error: ${e.message}")
PathFindingConfig.createDefault()
} catch (e: Exception) {
Log.e("PathFinding", "Failed to load config: ${e.message}")
PathFindingConfig.createDefault()
}
}
// Default configuration
fun PathFindingConfig.Companion.createDefault() = PathFindingConfig(
algorithm = "A*",
heuristicWeight = 1.0f,
allowDiagonalMovement = true,
enableCaching = true,
maxNodesExplored = 10000
)
Additional Safety Features: - Schema validation for JSON structure - Detailed error logging with line numbers - Graceful fallback to defaults - Configuration validation before use
Known Issues¶
Zero Known Issues
We're proud to announce that version 0.3.2 has no known critical or major issues!
All reported bugs from previous versions have been resolved, and extensive testing across multiple device configurations has not revealed any significant problems.
Testing Coverage:
- โ Path finding on 50+ different map configurations
- โ Navigation across 20+ device models
- โ Stress testing with complex multi-floor routes
- โ Memory leak testing with 8+ hour sessions
- โ Performance testing on low-end devices
- โ UI testing across all screen sizes
If you encounter any issues, please report them immediately:
Upgrade from v0.2.1¶
Breaking Changes¶
Minor Breaking Changes
This release includes a few minor API changes that may require code updates.
PathFinder Constructor¶
Before (v0.2.1):
val pathFinder = PathFinder(context)
After (v0.3.2):
val pathFinder = PathFindingUtil(sceneView)
// Now requires MineSceneView instead of Context
Route Options¶
Before:
val route = pathFinder.findPath(start, end, accessible = true)
After:
val options = RouteOptions(accessibleOnly = true)
val route = pathFinder.findPath(start, end, options)
Migration Steps¶
- Update Dependency
=== "Gradle (Kotlin)"
```kotlin
dependencies {
implementation("com.machinestalk:indoornavigationengine:0.3.2-alpha")
}
```
=== "Gradle (Groovy)"
```groovy
dependencies {
implementation 'com.machinestalk:indoornavigationengine:0.3.2-alpha'
}
```
-
Sync and Clean Build
./gradlew clean build -
Update PathFinder Initialization
// Old val pathFinder = PathFinder(context) // New val pathFinder = PathFindingUtil(sceneView) -
Update Route Options
// Old val route = pathFinder.findPath(start, end, true) // New val options = RouteOptions(accessibleOnly = true) val route = pathFinder.findPath(start, end, options) -
Add Navigation UI Components (Optional)
sceneView.addUIComponent(NavigationInstructionPanel(context)) sceneView.addUIComponent(RouteProgressBar(context))
New Feature Integration¶
Take advantage of new features:
// Enable path finding optimizations
PathFindingUtil.enableCaching(maxCacheSize = 100)
sceneView.preprocessNavigationGraph()
// Use new UI components
val instructionPanel = NavigationInstructionPanel(this)
val progressBar = RouteProgressBar(this)
sceneView.apply {
addUIComponent(instructionPanel)
addUIComponent(progressBar)
}
// Implement real-time navigation
pathFinder.startNavigation(route) { instruction ->
instructionPanel.showInstruction(instruction)
}
Testing & Quality¶
Test Coverage¶
| Component | Unit Tests | Integration | Coverage |
|---|---|---|---|
| Path Finding Core | โ 156 tests | โ 45 tests | 94% |
| A* Algorithm | โ 78 tests | โ 22 tests | 96% |
| UI Components | โ 89 tests | โ 34 tests | 88% |
| Route Calculation | โ 112 tests | โ 38 tests | 92% |
| Graph Processing | โ 67 tests | โ 18 tests | 90% |
Device Testing Matrix¶
| Device Category | Models Tested | Pass Rate | Notes |
|---|---|---|---|
| Flagship Phones | 15 models | 100% โ | Excellent performance |
| Mid-range Phones | 22 models | 100% โ | Good performance |
| Budget Phones | 18 models | 98% โ | Minor lag on 2 models |
| Tablets (7"-8") | 8 models | 100% โ | Optimal experience |
| Tablets (10"+) | 12 models | 100% โ | Outstanding UX |
Performance Benchmarks¶
Path Finding Performance:
| Map Complexity | Avg. Time | Max Time | Success Rate |
|---|---|---|---|
| Simple (< 100 nodes) | 12ms | 25ms | 100% |
| Medium (100-500 nodes) | 45ms | 95ms | 100% |
| Complex (500-1000 nodes) | 120ms | 280ms | 99.8% |
| Very Complex (> 1000 nodes) | 350ms | 720ms | 99.5% |
Memory Footprint:
- Idle: 28MB (โฌ๏ธ 38% from v0.2.1)
- Active Navigation: 42MB (โฌ๏ธ 32% from v0.2.1)
- Peak Usage: 68MB (โฌ๏ธ 25% from v0.2.1)
What's Next - v0.4.0¶
We're already working on the next exciting features:
Confirmed Features¶
- ๐บ๏ธ Offline Map Support - Download maps for offline navigation
- ๐ Proximity Alerts - Notifications when approaching destinations
- ๐ Analytics Dashboard - Usage statistics and insights
- ๐ค Voice Guidance - Audio turn-by-turn directions
- ๐ Multi-Language Support - Internationalization
- โฟ Enhanced Accessibility - More accessibility options
Under Consideration¶
- ๐ฎ AR Navigation Mode - Augmented reality wayfinding
- ๐ค Crowd Routing - Avoid crowded areas
- ๐ ฟ๏ธ Parking Integration - Find and navigate to parking
- ๐ข Building Directory - Interactive tenant/store listings
- ๐ฑ Widget Support - Quick navigation widgets
Timeline¶
Expected Release: Q4 2024
Beta Program: Starting October 2024
Complete Navigation Example¶
Here's a comprehensive example implementing all path finding features:
package com.example.indoornavapp
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.machinestalk.indoornavigationengine.ui.MineSceneView
import com.machinestalk.indoornavigationengine.ui.*
import com.machinestalk.indoornavigationengine.util.*
import com.machinestalk.indoornavigationengine.models.*
class NavigationActivity : AppCompatActivity() {
private lateinit var sceneView: MineSceneView
private lateinit var pathFinder: PathFindingUtil
private lateinit var instructionPanel: NavigationInstructionPanel
private lateinit var progressBar: RouteProgressBar
private var currentRoute: Route? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Setup scene
sceneView = MineSceneView(this)
setContentView(sceneView)
// Load map
val mapData = JsonUtil.LoadJsonFromAsset(this, "maps/mall.json")
mapData?.let { sceneView.setMapData(it) }
// Initialize path finding
setupPathFinding()
// Setup UI components
setupNavigationUI()
}
private fun setupPathFinding() {
pathFinder = PathFindingUtil(sceneView)
// Enable optimizations
PathFindingUtil.enableCaching(maxCacheSize = 100)
sceneView.preprocessNavigationGraph(
granularity = GraphGranularity.HIGH
)
}
private fun setupNavigationUI() {
// Instruction panel
instructionPanel = NavigationInstructionPanel(this).apply {
setPosition(NavigationInstructionPanel.Position.TOP_CENTER)
}
sceneView.addUIComponent(instructionPanel)
// Progress bar
progressBar = RouteProgressBar(this).apply {
setPosition(RouteProgressBar.Position.BOTTOM)
enableAutoUpdate = true
}
sceneView.addUIComponent(progressBar)
}
fun navigateToDestination(destinationId: String) {
val currentLocation = getCurrentLocation()
val destination = sceneView.getPOIById(destinationId)
if (destination != null) {
calculateAndStartNavigation(currentLocation, destination.location)
}
}
private fun calculateAndStartNavigation(
start: Location,
destination: Location
) {
// Show loading
showLoading()
// Calculate route
val options = RouteOptions(
accessibleOnly = false,
preferElevators = true
)
val route = pathFinder.findPath(start, destination, options)
route?.let {
currentRoute = it
// Display route on map
sceneView.drawRoute(
route = it,
color = getColor(R.color.route_color),
width = 8f,
animated = true
)
// Setup navigation UI
val distance = pathFinder.calculateDistance(it)
val time = (distance / 1.4f).toInt()
progressBar.apply {
setTotalDistance(distance)
setEstimatedTime(time)
}
// Start turn-by-turn navigation
pathFinder.startNavigation(it) { instruction ->
instructionPanel.showInstruction(
action = instruction.action,
distance = instruction.distance,
description = instruction.description
)
}
hideLoading()
} ?: run {
hideLoading()
showError("Unable to calculate route")
}
}
override fun onDestroy() {
pathFinder.stopNavigation()
super.onDestroy()
}
}
Feedback & Support¶
We value your feedback!
-
Report Issues
Found a problem? Let us know!
-
Feature Requests
Have ideas for navigation features?
-
Get Help
Need assistance with path finding?
-
Share Feedback
Tell us about your experience
Additional Resources¶
- ๐งญ Navigation Features Guide - Detailed navigation documentation
- ๐ Path Finding Guide - Advanced path finding techniques
- ๐จ UI Components Guide - UI component reference
- ๐ Quick Start - Get started quickly
- ๐ป Usage Guide - Comprehensive usage examples
- ๐ API Reference - Complete API documentation
- โ FAQ - Frequently asked questions
Acknowledgments¶
Special thanks to our beta testers and early adopters who provided invaluable feedback on the path finding system!
License¶
This software is released under the commercial license. Please review the license terms before use.
๐ Welcome to the Future of Indoor Navigation!
Version 0.3.2 brings powerful path finding capabilities to your fingertips. Start building amazing navigation experiences today!