mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-03-24 08:41:40 -04:00
fix: auto-detect and convert pixel zone coordinates to percentages in web layer
When zone coordinates are stored as pixel values (e.g. from a missed DB migration), the web layer now detects values > 100 and converts them to percentages using the monitor's dimensions, mirroring the existing C++ detection logic in zm_zone.cpp. This prevents limitPoints() from clamping pixel values to 0-100 and zones rendering incorrectly in SVG overlays. - Add convertPixelPointsToPercent() helper in functions.php - Call conversion before limitPoints() in zone.php and zones.php - Update Zone::svg_polygon() to accept monitor dimensions and convert - Pass ViewWidth/ViewHeight to svg_polygon() from Monitor::getStreamHTML() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1214,13 +1214,13 @@ class Monitor extends ZM_Object {
|
||||
foreach ($options['zones'] as $zone_id) {
|
||||
$zone = new Zone($zone_id);
|
||||
if ($zone->Id() and $zone->MonitorId() == $this->Id()) {
|
||||
$html .= $zone->svg_polygon();
|
||||
$html .= $zone->svg_polygon($this->ViewWidth(), $this->ViewHeight());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// true: render all zones for this monitor
|
||||
foreach (Zone::find(array('MonitorId'=>$this->Id()), array('order'=>'Area DESC')) as $zone) {
|
||||
$html .= $zone->svg_polygon();
|
||||
$html .= $zone->svg_polygon($this->ViewWidth(), $this->ViewHeight());
|
||||
}
|
||||
}
|
||||
if (isset($options['zones_extra'])) {
|
||||
|
||||
@@ -59,8 +59,27 @@ class Zone extends ZM_Object {
|
||||
return preg_replace('/\s+/', ',', $this->Coords());
|
||||
}
|
||||
|
||||
public function svg_polygon() {
|
||||
return '<polygon points="'.$this->AreaCoords().'" class="'.$this->Type().'" data-mid="'.$this->MonitorId().'" data-zid="'.$this->Id().'"><title>'.$this->Name().'</title></polygon>';
|
||||
public function svg_polygon($width=0, $height=0) {
|
||||
$areaCoords = $this->AreaCoords();
|
||||
if ($width && $height) {
|
||||
$points = coordsToPoints($this->Coords());
|
||||
$isPixel = false;
|
||||
foreach ($points as $point) {
|
||||
if ($point['x'] > 100 || $point['y'] > 100) {
|
||||
$isPixel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($isPixel) {
|
||||
foreach ($points as &$point) {
|
||||
$point['x'] = round($point['x'] / $width * 100, 2);
|
||||
$point['y'] = round($point['y'] / $height * 100, 2);
|
||||
}
|
||||
unset($point);
|
||||
$areaCoords = preg_replace('/\s+/', ',', pointsToCoords($points));
|
||||
}
|
||||
}
|
||||
return '<polygon points="'.$areaCoords.'" class="'.$this->Type().'" data-mid="'.$this->MonitorId().'" data-zid="'.$this->Id().'"><title>'.$this->Name().'</title></polygon>';
|
||||
}
|
||||
} # end class Zone
|
||||
?>
|
||||
|
||||
@@ -1466,6 +1466,24 @@ function limitPoints(&$points, $min_x, $min_y, $max_x, $max_y) {
|
||||
} // end foreach point
|
||||
} // end function limitPoints( $points, $min_x, $min_y, $max_x, $max_y )
|
||||
|
||||
function convertPixelPointsToPercent(&$points, $width, $height) {
|
||||
if (!$width || !$height) return;
|
||||
$isPixel = false;
|
||||
foreach ($points as $point) {
|
||||
if ($point['x'] > 100 || $point['y'] > 100) {
|
||||
$isPixel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($isPixel) {
|
||||
foreach ($points as &$point) {
|
||||
$point['x'] = round($point['x'] / $width * 100, 2);
|
||||
$point['y'] = round($point['y'] / $height * 100, 2);
|
||||
}
|
||||
unset($point);
|
||||
}
|
||||
}
|
||||
|
||||
function scalePoints(&$points, $scale) {
|
||||
foreach ( $points as &$point ) {
|
||||
$point['x'] = reScale($point['x'], $scale);
|
||||
|
||||
@@ -94,6 +94,9 @@ if ( !isset($zone) ) {
|
||||
$zone['AreaCoords'] = preg_replace('/\s+/', ',', $zone['Coords']);
|
||||
} # end if new Zone
|
||||
|
||||
# Auto-detect pixel coordinates and convert to percentages
|
||||
convertPixelPointsToPercent($zone['Points'], $monitor->ViewWidth(), $monitor->ViewHeight());
|
||||
|
||||
# Ensure Zone fits within the limits of the Monitor
|
||||
limitPoints($zone['Points'], $minX, $minY, $maxX, $maxY);
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ echo getNavBarHTML();
|
||||
}
|
||||
}
|
||||
|
||||
convertPixelPointsToPercent($row['Points'], $monitor->ViewWidth(), $monitor->ViewHeight());
|
||||
limitPoints($row['Points'], $minX, $minY, $maxX, $maxY);
|
||||
$row['Coords'] = pointsToCoords($row['Points']);
|
||||
$row['AreaCoords'] = preg_replace('/\s+/', ',', $row['Coords']);
|
||||
|
||||
Reference in New Issue
Block a user