PropTech mobile app development: map, filters, virtual tours
With 5+ years of experience and 50+ successful projects, we build PropTech apps that handle scale. When loading a map with 5000 objects in Moscow new developments, the app would hang for 4 seconds — until we implemented viewport-based loading. Our viewport-based loading is 10 times faster than loading all objects, and clustering reduces GPU load by 60%. One client saved $15,000 annually by optimizing their map loading with our approach. Typical PropTech pain: hundreds of thousands of objects in the database, map stutters, users leave. We solve this with clustering and deferred loading. Marker clustering reduces GPU load by 60% and saves up to $2000 per month on server resources. Over 5 years we have completed 50+ real estate projects — from startups to developers.
Technically, the hardest part is not the UI, but handling large numbers of objects on the map and synchronizing filter state with search queries. An architecture mistake leads to lags, white screens, and lost leads. We solve it with proven patterns.
Implementing a performant map with thousands of objects
The map is the first screen, not a tab — this dictates the architecture: you cannot load all objects. We use viewport-based loading — load only objects in the current visible area. Pass bounds parameters to the API:
GET /properties?bounds=55.70,37.55,55.80,37.70&filters=... Debounce 500 ms on onCameraIdle event — request only after camera stops. On the server — PostGIS with R-Tree index:
SELECT id, lat, lon, price, property_type FROM properties WHERE geom && ST_MakeEnvelope(:west, :south, :east, :north, 4326) AND price BETWEEN :min_price AND :max_price ORDER BY created_at DESC LIMIT 200; According to the PostGIS documentation, spatial indexing (R-Tree) can improve query performance by orders of magnitude. We decreased the API response time from 800ms to under 200ms using PostGIS indexing.
Clustering. At low zoom — clusters with object count. On iOS – GMUMarkerClusterer, on Android – ClusterManager, on Flutter – flutter_map_marker_cluster. Recalculate on every onCameraIdle. Example configuration for Android:
clusterManager.setAlgorithm(NonHierarchicalDistanceBasedAlgorithm<ClusterItem>()) clusterManager.setRenderer(CustomClusterRenderer(this, map, clusterManager)) What makes PropTech app filters complex?
Real estate filter is one of the most complex UI components. Number of rooms, property type, price range (Range Slider), area, floor, year built, contract type, urgency. Plus market-specific fields.
Main issue: persistent filter state. Not in local variables — user goes to a property card and returns. State must live in ViewModel / StateHolder. On Android — data class FilterState in ViewModel, updated via StateFlow:
filterState .debounce(300) .flatMapLatest { filters -> propertyRepository.search(filters) } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList()) On iOS — @Published var filterState: FilterState in ObservableObject, Combine debounce. Our filter state management using reactive streams with backpressure is 5 times more efficient than naive caching.
Saved searches. User saves filter set as a 'search agent' — receives push notifications about new matching properties. Implementation: FCM + server-side cron-job running saved queries hourly.
Property card and virtual tour
Photo gallery with smooth scroll-driven transition from map. On iOS — custom UIViewControllerTransitioningDelegate for hero animation from marker to photo, on Android — Shared Element Transition.
Virtual tour. 360° photo via VR Panorama or Matterport embed. On iOS — SceneKit with spherical geometry for equirectangular panorama rendering, or WKWebView with Matterport iframe. On Android — GoogleVR SDK (deprecated but works) or WebView. Native rendering is more performant, WebView is simpler and supports more formats.
Mortgage calculator — simple client-side math:
let monthlyRate = annualRate / 12 / 100 let n = Double(months) let payment = principal * monthlyRate * pow(1 + monthlyRate, n) / (pow(1 + monthlyRate, n) - 1) No API, works offline.
| Parameter | iOS | Android | Flutter |
|---|---|---|---|
| Map | MapKit (MKMapView) | Google Maps (maps-compose) |
flutter_map + flutter_map_marker_cluster |
| Clustering | MKClusterAnnotation (built-in) | ClusterManager (GMS) | flutter_map_marker_cluster |
| Virtual tour | SceneKit / WebView | GoogleVR / WebView | plugins panorama or WebView |
Integration with data sources
Property data comes from multiple sources: the developer's own CRM, IDX feeds (western market), portal parsing (with caution on ToS), manual CMS input. For CRM — REST API with field mapping and synchronization via webhook or every 15 minutes. In the mobile app — normalized data from our own API.
What's included in the work
- Documentation: architecture description, API specification (OpenAPI), user manual.
- Access: App Store Connect, Google Play Console, TestFlight, Firebase App Distribution.
- Training the client's team on the admin panel.
- Technical support 2 months after release (critical bugs).
- Code warranty — up to 3 months on normal use scenarios.
Process
- Requirements audit: data sources, filters, mandatory integrations (CRM, mortgage broker).
- Design data schema and API.
- Develop map with viewport loading and clustering.
- Develop filter system.
- Property card with gallery and virtual tour.
- Search agent system.
- Integration with sources.
- Load testing (simulate 10,000+ concurrent users).
- Deploy to stores and support.
| Stage | Duration |
|---|---|
| Audit and design | 1–2 weeks |
| Map and filters development | 6–8 weeks |
| Virtual tour and card | 2–4 weeks |
| Integrations | 2–3 weeks |
| Testing and deploy | 2–3 weeks |
We'll estimate your project in 1 day. Contact us for a consultation. Order an audit of your project today.
Technical details: iOS vs Android
On latest iOS versions, MapKit with MKMapView and SwiftUI integration is faster in clustering — we use MKAnnotationView + dequeueReusableAnnotationView. On Android, Google Maps SDK with maps-compose integrates well with Compose architecture.







