403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/lpost.delivery/lib/main/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/lpost.delivery/lib/main/sbpolygonengine.php
<?php

namespace Lpost\Delivery\Main;

class sbPolygonEngine
{
    public $map_width = 500;
    public $map_height = 500;

    public $polygon_coordinates = [];

    //list of the polygon lines, that together create a polygon ([x1, y1, x2, y2])
    public $polygon_bounds = [];

    public $point_to_check = [];

    // lines we use to create perpendicular from $bounds_box to $point_to_check
    public $perpendicularityLines = [];

    public $bounds_box = [
        'x1' => 0,
        'y1' => 0,
        'x2' => 0,
        'y2' => 0,
    ];

    // coords used to positionate coordinates to initial position (x=0, y=0) on dump visualization in case of zooming
    public $zoomOffset = [
        'minX' => 0,
        'minY' => 0,
    ];

    /*
     * Arg: polygon_coordinates
     * Example: [
                    [55.761515, 37.600375],
                    [55.759428, 37.651156],
                    [55.737112, 37.649566],
                    [55.737649, 37.597301],
                ]

        Methods:
        Ч isCrossesWith
        Ч previewBounds
     */
    public function __construct($polygon_coordinates)
    {
        $this->loadPolygon($polygon_coordinates);
    }

    private function preparePolygonVars()
    {
        $this->polygon_bounds = [];

        $this->perpendicularityLines = [
            'linetop' => [], // x1, y1, x2, y2 (from, from, to, to, crosses_ticks)
            'linebottom' => [],
            'lineleft' => [],
            'lineright' => [],
        ];

        $this->bounds_box = [
            'x1' => 0,
            'y1' => 0,
            'x2' => 0,
            'y2' => 0,
        ];
    }

    public function loadPolygon($polygon_coordinates)
    {

        //$this->point_to_check = [55.757856, 37.600000];

        $this->polygon_coordinates = $polygon_coordinates;

        $this->preparePolygonVars();


        foreach ($this->polygon_coordinates as $_key => $_list)
            $this->polygon_coordinates[$_key]['coords'] = $this->convertLatLngIntoCoords($_list[0], $_list[1]);


        foreach ($this->polygon_coordinates as $_key => $_list) {

            $nextKey = 0;
            if (isset($this->polygon_coordinates[$_key + 1]))
                $nextKey = $_key + 1;


            $_list_next = $this->polygon_coordinates[$nextKey];

            $this->polygon_bounds[] = ['x1' => $_list['coords']['x'], 'y1' => $_list['coords']['y'], 'x2' => $_list_next['coords']['x'], 'y2' => $_list_next['coords']['y'],];
        }
    }

    public function calculateZoomCooficient()
    {
        $zoomCooficient = 0.1;

        // zoom cooeficient calculate

        while (true) {

            $isZoomMaximumFound = false;

            foreach ($this->polygon_bounds as $_key => $_point) {

                $x1 = ($this->zoomed_bounds[$_key]['x1'] - $this->zoomOffset['minX']) * $zoomCooficient;
                $y1 = ($this->zoomed_bounds[$_key]['y1'] - $this->zoomOffset['minY']) * $zoomCooficient;
                $x2 = ($this->zoomed_bounds[$_key]['x2'] - $this->zoomOffset['minX']) * $zoomCooficient;
                $y2 = ($this->zoomed_bounds[$_key]['y2'] - $this->zoomOffset['minY']) * $zoomCooficient;

                if ($x1 >= $this->map_width or $x2 >= $this->map_width) {
                    $isZoomMaximumFound = true;
                    break;
                }

                if ($y1 >= $this->map_height or $y2 >= $this->map_height) {
                    $isZoomMaximumFound = true;
                    break;
                }

                $zoomCooficient++;
            }

            if ($isZoomMaximumFound) {
                $zoomCooficient--;
                $zoomCooficient--;
                break;
            }
        }

        return $zoomCooficient;
    }

    public function previewBounds($draw_perpendicular = true, $draw_center_dot = true)
    {
        $final = imagecreate($this->map_width, $this->map_height);

        // color is allocated for the background
        $white = imagecolorallocate($final, 255, 255, 255); // color of text

        $redColor = imagecolorallocate($final, 255, 0, 0); // color of text
        $blueColor = imagecolorallocate($final, 0, 0, 255); // color of text
        $greenColor = imagecolorallocate($final, 0, 255, 0); // color of text

        //print '<pre>' . print_r($this->polygon_coordinates, true) . '</pre>';

        $this->zoomOffset['minX'] = 0;
        $this->zoomOffset['minY'] = 0;

        foreach ($this->polygon_coordinates as $_point) {

            if ($this->zoomOffset['minX'] == 0 or $_point['coords']['x'] < $this->zoomOffset['minX'])
                $this->zoomOffset['minX'] = $_point['coords']['x'];

            if ($this->zoomOffset['minY'] == 0 or $_point['coords']['y'] < $this->zoomOffset['minY'])
                $this->zoomOffset['minY'] = $_point['coords']['y'];

        }

        $this->zoomed_bounds = $this->polygon_bounds;

        $zoomCooficient = $this->calculateZoomCooficient();

        foreach ($this->zoomed_bounds as $_key => $_point) {

            // обнул¤ем систему координат
            $this->zoomed_bounds[$_key]['x1'] -= $this->zoomOffset['minX'];
            $this->zoomed_bounds[$_key]['y1'] -= $this->zoomOffset['minY'];
            $this->zoomed_bounds[$_key]['x2'] -= $this->zoomOffset['minX'];
            $this->zoomed_bounds[$_key]['y2'] -= $this->zoomOffset['minY'];

            $this->zoomed_bounds[$_key]['x1'] *= $zoomCooficient;
            $this->zoomed_bounds[$_key]['y1'] *= $zoomCooficient;
            $this->zoomed_bounds[$_key]['x2'] *= $zoomCooficient;
            $this->zoomed_bounds[$_key]['y2'] *= $zoomCooficient;

            imageline($final, $this->zoomed_bounds[$_key]['x1'], $this->zoomed_bounds[$_key]['y1'], $this->zoomed_bounds[$_key]['x2'], $this->zoomed_bounds[$_key]['y2'], $redColor);
        }

        foreach ($this->zoomed_bounds as $_point) {

            //print '<pre>' . print_r($_point, true) . '</pre>';

            imagesetpixel($final, $_point['x1'], $_point['y1'], $blueColor);

        }

        if ($draw_perpendicular) {

            foreach ($this->perpendicularityLines as $_line) {

                // обнул¤ем систему координат
                $_line['x1'] -= $this->zoomOffset['minX'];
                $_line['y1'] -= $this->zoomOffset['minY'];
                $_line['x2'] -= $this->zoomOffset['minX'];
                $_line['y2'] -= $this->zoomOffset['minY'];

                $_line['x1'] *= $zoomCooficient;
                $_line['y1'] *= $zoomCooficient;
                $_line['x2'] *= $zoomCooficient;
                $_line['y2'] *= $zoomCooficient;

                imageline($final, $_line['x1'], $_line['y1'], $_line['x2'], $_line['y2'], $blueColor);

            }

            //print '<pre>' . print_r($this->perpendicularityLines, true) . '</pre>';

        }

        if ($draw_center_dot) {

            // обнул¤ем систему координат
            $this->point_to_check['coords']['x'] -= $this->zoomOffset['minX'];
            $this->point_to_check['coords']['y'] -= $this->zoomOffset['minY'];

            $this->point_to_check['coords']['x'] *= $zoomCooficient;
            $this->point_to_check['coords']['y'] *= $zoomCooficient;


            imagesetpixel($final, $this->point_to_check['coords']['x'], $this->point_to_check['coords']['y'], $greenColor);

            //print '<pre>' . print_r($this->perpendicularityLines, true) . '</pre>';

        }


        ob_start();
        imagepng($final);
        // Capture the output and clear the output buffer
        $imagedata = ob_get_clean();

        print '<img style="border: 1px solid lightgray;" src="data:image/jpeg;base64,' . base64_encode($imagedata) . '">';

        //exit();

    }

    private function calculateBoundsBox()
    {
        /**
         * calculation $bounds_box
         * lowest x is x1, biggest x is x2
         * lowest y is y1, biggest y is y2
         *
         */

        foreach ($this->polygon_coordinates as $point) {

            $x = $point['coords']['x'];
            $y = $point['coords']['y'];

            if ($x < $this->bounds_box['x1'] or $this->bounds_box['x1'] == 0)
                $this->bounds_box['x1'] = $x;

            if ($x > $this->bounds_box['x2'] or $this->bounds_box['x2'] == 0)
                $this->bounds_box['x2'] = $x;

            if ($y < $this->bounds_box['y1'] or $this->bounds_box['y1'] == 0)
                $this->bounds_box['y1'] = $y;

            if ($y > $this->bounds_box['y2'] or $this->bounds_box['y2'] == 0)
                $this->bounds_box['y2'] = $y;
        }
    }

    private function calculatePerpendicularityLines()
    {
        /**
         *
         * ѕроводим перпендикул¤ры от точки до граней boundsBox
         *
         */

        foreach ($this->perpendicularityLines as $_line_key => $list) {

            $lineInfo = ['x1' => 0, 'y1' => 0, 'x2' => $this->point_to_check['coords']['x'], 'y2' => $this->point_to_check['coords']['y'], 'crosses_ticks' => 0];

            /**
             * “ак как мы проводим перпендикул¤ры от провер¤мой точки к коробке полигона (bounds_box),
             * а затем провер¤ем пересечени¤ получившихс¤ перпендикул¤ров с гран¤ми полигона, то может возикнуть следующа¤ проблема:
             * если грань полигона полностью перпендикул¤рна (ровна¤!) нашему перпендикул¤ру, то он будет с ней не пересекатьс¤, а соприкасатьс¤ и дальнейша¤ арифметика не работает.
             * ѕоэтому, мы удлин¤ем каждый перпендикул¤р на коэффициент $logerityCoefficient
             */
            $logerityCoefficient = 0.000002;

            if ($_line_key == 'linetop') {

                $lineInfo['x1'] = $this->point_to_check['coords']['x'];
                $lineInfo['y1'] = $this->bounds_box['y1'] - $this->bounds_box['y1'] * $logerityCoefficient;

            }

            if ($_line_key == 'linebottom') {

                $lineInfo['x1'] = $this->point_to_check['coords']['x'];
                $lineInfo['y1'] = $this->bounds_box['y2'] + $this->bounds_box['y2'] * $logerityCoefficient;

            }

            if ($_line_key == 'lineleft') {

                $lineInfo['y1'] = $this->point_to_check['coords']['y'];
                $lineInfo['x1'] = $this->bounds_box['x1'] - $this->bounds_box['x1'] * $logerityCoefficient;

            }

            if ($_line_key == 'lineright') {

                $lineInfo['y1'] = $this->point_to_check['coords']['y'];
                $lineInfo['x1'] = $this->bounds_box['x2'] + $this->bounds_box['x2'] * $logerityCoefficient;

            }

            $this->perpendicularityLines[$_line_key] = $lineInfo;
        }

        //print '<pre>' . print_r($this->perpendicularityLines, true) . '</pre>';
    }

    public function isCrossesWith($lat, $lng)
    {

        $this->point_to_check = [$lat, $lng];

        $this->point_to_check['coords'] = $this->convertLatLngIntoCoords($lat, $lng);


        $this->calculateBoundsBox();

        $this->calculatePerpendicularityLines();

        $isCrosses = false;

        $this->isInsideBoundsBox = self::isPointInsideBoundsBox($this->point_to_check['coords']['x'], $this->point_to_check['coords']['y'], $this->bounds_box);

        /**
         * Ќеобходимо посчитать количество пересечений перпендикул¤ров с гран¤ми полигона. (“олько если точка находитс¤ внутри bounds_box
         */
        if ($this->isInsideBoundsBox)
            foreach ($this->perpendicularityLines as $_line_key => $_perendicular)
                foreach ($this->polygon_bounds as $_point) {


                    $isLinesCrosses = self::isLinesCrosses($_perendicular, $_point);

                    if ($isLinesCrosses)
                        $this->perpendicularityLines[$_line_key]['crosses_ticks']++;

                }

        /**
         * Point falls into a poligon if
         * 1. all the perpendicularity lines intersects ($_line['crosses_ticks']) with polygon at least 1 time
         * 2. or crosses_ticks is higher than 1 and even in the same time (3, 5, 7 etc)
         *
         * If at least one perpendicularity has different crosses_ticks amount then point doesn't fall into polygon
         */

        if ($isCrosses == false) {

            // предполагаем, что точка входит в полигон. ≈сли это не так - сбросим флаг в цикле ниже
            $isCrosses = true;

            foreach ($this->perpendicularityLines as $_line) {

                if ($_line['crosses_ticks'] == 0 or self::isOddNumber($_line['crosses_ticks']) == false)
                    $isCrosses = false;
            }
        }

        return $isCrosses;
    }

    static function isOddNumber($number)
    {

        if ($number % 2 == 0)
            return false;

        return true;
    }

    /**
     * Arg: latitude, longitude
     * Result: array with pixels position [x => 0, y => 0]
     */
    public function convertLatLngIntoCoords($lat, $lng)
    {

        $x = ($lng + 180) * ($this->map_width / 360);

        // convert from degrees to radians
        $lng_rad = $lat * M_PI / 180;

        // get y value
        $mercN = log(tan((M_PI / 4) + ($lng_rad / 2)));

        $y = ($this->map_height / 2) - ($this->map_width * $mercN / (2 * M_PI));

        return ['x' => $x, 'y' => $y];
    }

    /**
     * Does this point is inside the polygon box? (Polygon box is a raw rectangle which contain all the polygon)
     */
    static function isPointInsideBoundsBox($x, $y, $boundsBox)
    {

        if ($x < $boundsBox['x1'] or $x > $boundsBox['x2'])
            return false;

        if ($y < $boundsBox['y1'] or $y > $boundsBox['y2'])
            return false;

        return true;
    }

    /**
     * Binary operation on two vectors
     */
    static function getVectorCrossProduct($x1, $y1, $x2, $y2)
    {
        $result = $x1 * $y2 - $x2 * $y1;

        return $result;
    }

    /**
     * Get know does two vectors crosses each other
     * What is P1, P2, P3, P4 vectors? (http://grafika.me/node/237)
     *
     */
    static function isLinesCrosses($line1, $line2)
    {
        /* form vectors (coordinates) */
        $vectorP3P4 = [
            'x' => $line2['x2'] - $line2['x1'],
            'y' => $line2['y2'] - $line2['y1']
        ];
        $vectorP1P2 = [
            'x' => $line1['x2'] - $line1['x1'],
            'y' => $line1['y2'] - $line1['y1']
        ];

        $vectorP3P1 = [
            'x' => $line1['x1'] - $line2['x1'],
            'y' => $line1['y1'] - $line2['y1']
        ];

        $vectorP3P2 = [
            'x' => $line1['x2'] - $line2['x1'],
            'y' => $line1['y2'] - $line2['y1']
        ];

        $vectorP1P3 = [
            'x' => $line2['x1'] - $line1['x1'],
            'y' => $line2['y1'] - $line1['y1']
        ];

        $vectorP1P4 = [
            'x' => $line2['x2'] - $line1['x1'],
            'y' => $line2['y2'] - $line1['y1']
        ];

        $v1 = self::getVectorCrossProduct($vectorP3P4['x'], $vectorP3P4['y'], $vectorP3P1['x'], $vectorP3P1['y']);
        $v2 = self::getVectorCrossProduct($vectorP3P4['x'], $vectorP3P4['y'], $vectorP3P2['x'], $vectorP3P2['y']);

        $v3 = self::getVectorCrossProduct($vectorP1P2['x'], $vectorP1P2['y'], $vectorP1P3['x'], $vectorP1P3['y']);
        $v4 = self::getVectorCrossProduct($vectorP1P2['x'], $vectorP1P2['y'], $vectorP1P4['x'], $vectorP1P4['y']);

        if (self::isLessThenZeroWithPrecision($v1 * $v2) and self::isLessThenZeroWithPrecision($v3 * $v4))
            return true;

        return false;
    }

    static function isLessThenZeroWithPrecision($a)
    {
        $precision = 1e-15;

        return 0 - $a > $precision;
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit