mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-03-24 16:51:47 -04:00
Convert zone coordinates from absolute pixel values to percentages (0.00-100.00) so zones automatically adapt when monitor resolution changes. This eliminates the need to manually reconfigure zones after resolution adjustments. Changes: - Add DB migration (zm_update-1.37.81.sql) to convert existing pixel coords to percentages, recalculate area, and update Units default - Add Zone::ParsePercentagePolygon() in C++ to parse percentage coords and convert to pixels at runtime using monitor dimensions - Backwards compat: C++ Zone::Load() checks Units column and uses old pixel parser for legacy 'Pixels' zones - Update PHP coordsToPoints/mapCoords/getPolyArea for float coords, replace scanline area algorithm with shoelace formula - Update JS zone editor to work in percentage coordinate space with SVG viewBox "0 0 100 100" and non-scaling-stroke for consistent line thickness - Position zone SVG overlay inside imageFeed container via JS to align with image only (not status bar) - Support array of zone IDs in Monitor::getStreamHTML zones option - Update monitor resize handler: percentage coords don't need rescaling, only threshold pixel counts are adjusted - Add 8 Catch2 unit tests for ParsePercentagePolygon Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
67 lines
1.9 KiB
PHP
67 lines
1.9 KiB
PHP
<?php
|
|
namespace ZM;
|
|
require_once('database.php');
|
|
require_once('Object.php');
|
|
require_once('Monitor.php');
|
|
|
|
class Zone extends ZM_Object {
|
|
protected static $table = 'Zones';
|
|
|
|
protected $defaults = array(
|
|
'Id' => null,
|
|
'MonitorId' => null,
|
|
'Name' => '',
|
|
'Type' => 'Active',
|
|
'Units' => 'Percent',
|
|
'NumCoords' => '4',
|
|
'Coords' => '',
|
|
'Area' => '0',
|
|
'AlarmRGB' => 0xff0000,
|
|
'CheckMethod' => 'Blobs',
|
|
'MinPixelThreshold' => 25,
|
|
'MaxPixelThreshold' => null,
|
|
'MinAlarmPixels' => null,
|
|
'MaxAlarmPixels' => null,
|
|
'FilterX' => 3,
|
|
'FilterY' => 3,
|
|
'MinFilterPixels' => null,
|
|
'MaxFilterPixels' => null,
|
|
'MinBlobPixels' => null,
|
|
'MaxBlobPixels' => null,
|
|
'MinBlobs' => 1,
|
|
'MaxBlobs' => null,
|
|
'OverloadFrames' => 0,
|
|
'ExtendAlarmFrames' => 0,
|
|
);
|
|
|
|
public static function find( $parameters = array(), $options = array() ) {
|
|
return ZM_Object::_find(self::class, $parameters, $options);
|
|
}
|
|
|
|
public static function find_one( $parameters = array(), $options = array() ) {
|
|
return ZM_Object::_find_one(self::class, $parameters, $options);
|
|
}
|
|
|
|
public function Monitor() {
|
|
if (isset($this->{'MonitorId'})) {
|
|
$Monitor = Monitor::find_one(array('Id'=>$this->{'MonitorId'}));
|
|
if ( $Monitor )
|
|
return $Monitor;
|
|
}
|
|
return new Monitor();
|
|
}
|
|
|
|
public function Points() {
|
|
return coordsToPoints($this->Coords());
|
|
}
|
|
|
|
public function AreaCoords() {
|
|
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>';
|
|
}
|
|
} # end class Zone
|
|
?>
|