Replace heatmap with density dots for all zoom levels
Remove Leaflet.heat in favor of consistent density dot visualization: - Zoom 1-5: Density dots with 40% more density (24px spacing) - Zoom 6-11: Density dots with normal spacing (40px) - Zoom 12-15: Numbered cluster circles - Zoom 16+: Individual property markers Density dots provide clearer visualization than heatmap blobs for high-density property data. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,11 @@ class MLS_Cluster {
|
|||||||
*/
|
*/
|
||||||
const DENSITY_DOT_SPACING = 40;
|
const DENSITY_DOT_SPACING = 40;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denser spacing for very zoomed out views (40% more dense = 60% of normal)
|
||||||
|
*/
|
||||||
|
const DENSITY_DOT_SPACING_DENSE = 24;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum properties to return as individual markers
|
* Maximum properties to return as individual markers
|
||||||
* Above this threshold, return clusters
|
* Above this threshold, return clusters
|
||||||
@@ -37,8 +42,8 @@ class MLS_Cluster {
|
|||||||
/**
|
/**
|
||||||
* Zoom thresholds for visualization modes
|
* Zoom thresholds for visualization modes
|
||||||
*/
|
*/
|
||||||
const ZOOM_HEATMAP_MAX = 7; // 3-7: heatmap only
|
const ZOOM_DENSE_MAX = 5; // 1-5: density dots (40% more dense)
|
||||||
const ZOOM_DENSITY_MAX = 11; // 8-11: density dots
|
const ZOOM_DENSITY_MAX = 11; // 6-11: density dots (normal)
|
||||||
const ZOOM_CLUSTER_MAX = 15; // 12-15: numbered clusters
|
const ZOOM_CLUSTER_MAX = 15; // 12-15: numbered clusters
|
||||||
// 16+: individual markers
|
// 16+: individual markers
|
||||||
|
|
||||||
@@ -274,14 +279,14 @@ class MLS_Cluster {
|
|||||||
$zoom = (int) $args['zoom'];
|
$zoom = (int) $args['zoom'];
|
||||||
|
|
||||||
// Determine visualization mode based on zoom level
|
// Determine visualization mode based on zoom level
|
||||||
// Zoom 3-7: Heatmap (just return points for client-side heatmap)
|
// Zoom 1-5: Density dots (40% more dense)
|
||||||
if ($zoom <= self::ZOOM_HEATMAP_MAX) {
|
if ($zoom <= self::ZOOM_DENSE_MAX) {
|
||||||
return $this->get_heatmap_data($where_sql, $values, $total);
|
return $this->get_density_data($where_sql, $values, $zoom, $center_lat, $total, self::DENSITY_DOT_SPACING_DENSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom 8-11: Density dots (small colored circles without numbers)
|
// Zoom 6-11: Density dots (normal spacing)
|
||||||
if ($zoom <= self::ZOOM_DENSITY_MAX) {
|
if ($zoom <= self::ZOOM_DENSITY_MAX) {
|
||||||
return $this->get_density_data($where_sql, $values, $zoom, $center_lat, $total);
|
return $this->get_density_data($where_sql, $values, $zoom, $center_lat, $total, self::DENSITY_DOT_SPACING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom 12-15: Numbered clusters (or individual if low count)
|
// Zoom 12-15: Numbered clusters (or individual if low count)
|
||||||
@@ -347,15 +352,17 @@ class MLS_Cluster {
|
|||||||
* @param int $zoom Map zoom level
|
* @param int $zoom Map zoom level
|
||||||
* @param float $center_lat Center latitude for Mercator adjustment
|
* @param float $center_lat Center latitude for Mercator adjustment
|
||||||
* @param int $total Total count
|
* @param int $total Total count
|
||||||
|
* @param int $pixel_spacing Pixel spacing for grid cells
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function get_density_data($where_sql, $values, $zoom, $center_lat, $total) {
|
private function get_density_data($where_sql, $values, $zoom, $center_lat, $total, $pixel_spacing = null) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$table = $this->db->properties_table();
|
$table = $this->db->properties_table();
|
||||||
|
$pixel_spacing = $pixel_spacing ?: self::DENSITY_DOT_SPACING;
|
||||||
|
|
||||||
// Use smaller grid cells for density dots
|
// Use smaller grid cells for density dots
|
||||||
list($lat_step, $lng_step) = $this->get_grid_step_for_zoom($zoom, $center_lat, self::DENSITY_DOT_SPACING);
|
list($lat_step, $lng_step) = $this->get_grid_step_for_zoom($zoom, $center_lat, $pixel_spacing);
|
||||||
|
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
FLOOR(latitude / %f) as lat_cell,
|
FLOOR(latitude / %f) as lat_cell,
|
||||||
|
|||||||
@@ -131,8 +131,6 @@ if (function_exists('mls_get_property_count')) {
|
|||||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
||||||
<!-- Leaflet MarkerCluster JS -->
|
<!-- Leaflet MarkerCluster JS -->
|
||||||
<script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js" crossorigin=""></script>
|
<script src="https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js" crossorigin=""></script>
|
||||||
<!-- Leaflet Heat JS -->
|
|
||||||
<script src="https://unpkg.com/leaflet.heat@0.2.0/dist/leaflet-heat.js" crossorigin=""></script>
|
|
||||||
<script>
|
<script>
|
||||||
var homeprozMapData = {
|
var homeprozMapData = {
|
||||||
isMapView: <?php echo $show_map ? 'true' : 'false'; ?>,
|
isMapView: <?php echo $show_map ? 'true' : 'false'; ?>,
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -16,8 +16,7 @@
|
|||||||
var PropertyMap = {
|
var PropertyMap = {
|
||||||
map: null,
|
map: null,
|
||||||
markers: {}, // Object keyed by property ID
|
markers: {}, // Object keyed by property ID
|
||||||
heatLayer: null, // Leaflet.heat layer for zoom 3-7
|
densityLayer: null, // Layer group for density dots (zoom 1-11)
|
||||||
densityLayer: null, // Layer group for density dots (zoom 8-11)
|
|
||||||
clusterLayer: null, // Layer group for server clusters (zoom 12-15)
|
clusterLayer: null, // Layer group for server clusters (zoom 12-15)
|
||||||
markerCluster: null, // MarkerClusterGroup for individual markers (zoom 16+)
|
markerCluster: null, // MarkerClusterGroup for individual markers (zoom 16+)
|
||||||
selectedPropertyId: null,
|
selectedPropertyId: null,
|
||||||
@@ -48,22 +47,7 @@
|
|||||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||||
}).addTo(this.map);
|
}).addTo(this.map);
|
||||||
|
|
||||||
// Create heatmap layer (zoom 3-7)
|
// Create layer for density dots (zoom 1-11)
|
||||||
this.heatLayer = L.heatLayer([], {
|
|
||||||
radius: 25,
|
|
||||||
blur: 15,
|
|
||||||
maxZoom: 10,
|
|
||||||
max: 1.0,
|
|
||||||
gradient: {
|
|
||||||
0.2: '#22c55e', // green
|
|
||||||
0.4: '#eab308', // yellow
|
|
||||||
0.6: '#f97316', // orange
|
|
||||||
0.8: '#ef4444', // red
|
|
||||||
1.0: '#dc2626' // dark red
|
|
||||||
}
|
|
||||||
}).addTo(this.map);
|
|
||||||
|
|
||||||
// Create layer for density dots (zoom 8-11)
|
|
||||||
this.densityLayer = L.layerGroup().addTo(this.map);
|
this.densityLayer = L.layerGroup().addTo(this.map);
|
||||||
|
|
||||||
// Create layer for server-side clusters (zoom 12-15)
|
// Create layer for server-side clusters (zoom 12-15)
|
||||||
@@ -160,9 +144,6 @@
|
|||||||
self.currentMode = data.type;
|
self.currentMode = data.type;
|
||||||
|
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'heatmap':
|
|
||||||
self.renderHeatmap(data.points);
|
|
||||||
break;
|
|
||||||
case 'density':
|
case 'density':
|
||||||
self.renderDensity(data.dots);
|
self.renderDensity(data.dots);
|
||||||
break;
|
break;
|
||||||
@@ -185,21 +166,12 @@
|
|||||||
* Clear all visualization layers
|
* Clear all visualization layers
|
||||||
*/
|
*/
|
||||||
clearAllLayers: function() {
|
clearAllLayers: function() {
|
||||||
this.heatLayer.setLatLngs([]);
|
|
||||||
this.densityLayer.clearLayers();
|
this.densityLayer.clearLayers();
|
||||||
this.clusterLayer.clearLayers();
|
this.clusterLayer.clearLayers();
|
||||||
this.markerCluster.clearLayers();
|
this.markerCluster.clearLayers();
|
||||||
this.markers = {};
|
this.markers = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Render heatmap (zoom 3-7)
|
|
||||||
*/
|
|
||||||
renderHeatmap: function(points) {
|
|
||||||
this.clearAllLayers();
|
|
||||||
this.heatLayer.setLatLngs(points);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render density dots (zoom 8-11)
|
* Render density dots (zoom 8-11)
|
||||||
* Small colored circles based on property count
|
* Small colored circles based on property count
|
||||||
|
|||||||
Reference in New Issue
Block a user