/** * @AjaxCallable=TRUE * @AjaxMethod=POST * @AjaxAsync=TRUE */ public function loadData() { $this->load->library('geo/*'); $this->load->model('POIModel'); $this->load->model('LabelModel'); // Helper functions function addFlag(&$res, $flag) { in_array($flag, $res['flags']) ? null : ($res['flags'][] = $flag); } function hasFlag($res, $flag) { return in_array($flag, $res); } function addLabels(&$res, $labels) { $res['labels'] = array_merge($res['labels'], $labels); } // Required params $vBoundsWKT = filter_input(INPUT_POST, 'vBounds', FILTER_SANITIZE_STRING); $zoom = filter_input(INPUT_POST, 'zoom', FILTER_VALIDATE_INT); // Optional params, need to normalise if not present $types = filter_input(INPUT_POST, 'types', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY); $poiId = filter_input(INPUT_POST, 'poiId', FILTER_VALIDATE_INT); $poiIds = filter_input(INPUT_POST, 'poiIds', FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY); $flags = filter_input(INPUT_POST, 'flags', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY); $vBounds = ViewBounds::fromWKT($vBoundsWKT); // Normalise parameters if ($types === NULL) { $types = []; } if ($poiId === NULL) { $poiId = 0; } if ($poiIds === NULL) { $poiIds = []; } if ($flags === NULL) { $flags = []; } // Prepare result object $res = ['labels' => [], 'flags' => []]; if ($poiId !== 0 && !hasFlag($flags, 'excludePoiLabel')) { $poi = POIModel::load($poiId); $res['labels'][] = LabelModel::loadDynamic($poiId); $res['poi'] = []; addFlag($res, 'doLabelling'); // Load poi info if (hasFlag($flags, 'poiInfo')) { $res['poi']['info'] = $poi->toObject(); } // Load poi card if (hasFlag($flags, 'poiCard')) { $res['poi']['card'] = "<div>Card</div>"; addFlag($res, 'showCard'); } // Pan to poi and fit border or adjust zoom accordingly if (hasFlag($flags, 'panToPoi')) { $border = $poi->border(); if ($border === NULL) { $vBounds->setCenter($poi->latLng()); $vBounds->changeZoom(14 - $zoom); $zoom = 14; } else { $borderBounds = ViewBounds::fromPolygon($border); $vBounds->fitBounds($borderBounds, $zoom); } addFlag($res, 'panToCenter'); } } if (count($poiIds) > 0) { // Load labels by poiIds addLabels($res, LabelModel::loadDynamicByIds($poiIds)); if (hasFlag($flags, 'zoomToPois')) { // Load pois for their positions and borders $pois = POIModel::loadByIds($poiIds); // Expand pois if ($poiId !== 0) { $poi = POIModel::load($poiId); $pois = array_merge($pois, [$poi]); } // Initialise bounds and extend by all pois $bounds = new ViewBounds($pois[0]->latLng(), $pois[0]->latLng()); for ($i = 1; $i < count($pois); $i++) { if ($pois[$i]->border() === NULL) { $bounds->extendByLatLng($pois[$i]->latLng()); } else { $borderBounds = ViewBounds::fromPolygon($pois[$i]->border()); $bounds->extendByBounds($borderBounds); } } $vBounds->fitBounds($bounds, $zoom); $bounds->buffer(30, 30, $zoom); $vBounds->fitBounds($bounds, $zoom); } addFlag($res, 'panToCenter'); addFlag($res, 'doLabelling'); } if (count($types) > 0) { $bounds = $vBounds->toBounds(); if (in_array('zoomToTypes', $flags)) { $guard = 18; // while (!LabelModel::typesWithinBounds($bounds, $types, $poiId) && --$guard > 0) { while (!LabelModel::oneOfTypesWithinBounds($bounds, $types, $poiId) && --$guard > 0) { $vBounds->zoomOut(); $bounds = $vBounds->toBounds(); $zoom--; addFlag($res, 'panToCenter'); } } addLabels($res, LabelModel::loadDynamicByBounds($bounds, $types, $poiId)); addFlag($res, 'doLabelling'); } if ($poiId !== 0 || $types !== NULL && count($types) > 0) { $bounds = $vBounds->toBounds(); $exceptIds = array_merge($poiIds, [$poiId]); addLabels($res, LabelModel::loadStaticDynamicByBounds($bounds, $zoom, $exceptIds, $types)); } else { $bounds = $vBounds->toBounds(); addLabels($res, LabelModel::loadStaticByBounds($bounds, $zoom)); } if (hasFlag($flags, 'newPois')) { // Parameter '1' TO BE changed to logged-in user's id $bounds = $vBounds->toBounds(); $res['new'] = LabelModel::loadNew($bounds, 1); } $res['center'] = $vBounds->getCenter()->toWKT(); $res['zoom'] = $zoom; return $res; }
function view() { $this->load->library('geo/*'); $this->load->model('POIModel'); $poiId = filter_input(INPUT_GET, 'poiId', FILTER_VALIDATE_INT); $poiObject = new stdClass(); $attrsObject = new stdClass(); $poi = POIModel::load($poiId); $poiObject->id = $poi->id(); $poiObject->name = $poi->name(); $poiObject->cat = $poi->cat(); $poiObject->sub = $poi->sub(); $poiObject->latLng = $poi->latLng(); $poiObject->border = $poi->border(); $attrsObject = $poi->attributes(); $r = sqrt(2 * pow(9, 2)); $sw = Geo::proximity($poi->latLng(), $r, 215); $ne = Geo::proximity($poi->latLng(), $r, 45); $vb = new ViewBounds($sw, $ne); $poiBorder = $vb->toPolygon(); $near = POIModel::loadByBorder($poiBorder, ['restaurant', 'supermarket', 'gasstation', 'anchorage', 'buoys'], 198); $nearSorted = []; $nearSortedIds = []; // Separate into subcategories foreach ($near as $poiTo) { $sub = $poiTo->sub(); if (!array_key_exists($sub, $nearSorted)) { $nearSorted[$sub] = []; $nearSortedIds[$sub] = []; } $nearSorted[$sub][] = ['poi' => $poiTo->toObject(), 'dist' => Geo::haversine($poi->latLng(), $poiTo->latLng())]; $nearSortedIds[$sub][] = $poiTo->id(); } // Sort each subcategory by disance foreach ($nearSorted as &$near) { aasort($near, 'dist'); } $this->assign('poi', $poiObject); $this->assign('attrs', $attrsObject); $this->assign('near', (object) $nearSorted); $this->assign('nearIds', $nearSortedIds); $this->load->view('templates/view'); }
/** * @param ViewBounds $bounds */ public function fitBounds(ViewBounds $bounds, &$zoom = NULL) { // Set centre to given bounds centre $this->setCenter($bounds->getCenter()); // Mercator-project bounds' north and south latitudes $aLatDiff = merLat($this->n) - merLat($this->s); $bLatDiff = merLat($bounds->n()) - merLat($bounds->s()); // Compute meridian zoom difference $latZoomDiff = floor((log($aLatDiff) - log($bLatDiff)) / log(2) + 0.001); // Compute parallel differences for this and given bounds $aLngDiff = $this->e - $this->w; $bLngDiff = $bounds->e() - $bounds->w(); // Compute parallel zoom difference $lngZoomDiff = floor((log($aLngDiff) - log($bLngDiff)) / log(2) + 0.001); // Change zoom using smaller of the two computed zoom differences $zoomDiff = min($latZoomDiff, $lngZoomDiff); $this->changeZoom($zoomDiff); // Update zoom if given if ($zoom !== NULL) { $zoom += $zoomDiff; } }
/** * @AjaxCallable=TRUE * @AjaxMethod=POST * @AjaxAsync=TRUE */ function loadData() { // Required params $vBoundsWKT = filter_input(INPUT_POST, 'vBounds', FILTER_SANITIZE_STRING); $zoom = filter_input(INPUT_POST, 'zoom', FILTER_VALIDATE_INT); // Optional params, need to normalise if not present $types = filter_input(INPUT_POST, 'types', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY); $poiId = filter_input(INPUT_POST, 'poiId', FILTER_VALIDATE_INT); $flags = filter_input(INPUT_POST, 'flags', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY); $vBounds = ViewBounds::fromWKT($vBoundsWKT); // Normalise parameters if ($types === NULL) { $types = []; } if ($poiId === NULL) { $poiId = 0; } if ($flags === NULL) { $flags = []; } // Prepare result object $res = ['labels' => [], 'flags' => []]; if (in_array('poiInfo', $flags) || in_array('poiCard', $flags) || in_array('panToPoi', $flags)) { $poi = POIModel::load($poiId); $res['poi'] = []; // Load poi info if (in_array('poiInfo', $flags)) { $res['poi']['info'] = $poi->info(); } // Load poi card if (in_array('poiCard', $flags)) { $res['poi']['card'] = "<div>Card</div>"; $res['flags'][] = "showCard"; } // Pan to poi and fit border or adjust zoom accordingly if (in_array('panToPoi', $flags)) { $border = $poi->border(); if ($border === NULL) { $vBounds->setCenter($poi->latLng()); $vBounds->changeZoom(14 - $zoom); $zoom = 14; } else { $borderBounds = ViewBounds::fromPolygon($border); $vBounds->fitBounds($borderBounds, $zoom); } $res['flags'][] = "panToCenter"; } } if ($types !== NULL) { $bounds = $vBounds->toBounds(); if (in_array('zoomToTypes', $flags)) { $guard = 18; while (!LabelModel::typesWithinBounds($bounds, $types, $poiId) && --$guard > 0) { $vBounds->zoomOut(); $bounds = $vBounds->toBounds(); $zoom--; } $res['flags'][] = "panToCenter"; } $res['labels'] = LabelModel::loadDynamicByBounds($bounds, $types, $poiId); $res['flags'][] = "doLabelling"; } if ($types !== NULL && count($types) > 0) { $bounds = $vBounds->toBounds(); $res['labels'] = array_merge($res['labels'], LabelModel::loadStaticDynamicByBounds($bounds, $zoom, 0, $types)); } else { $bounds = $vBounds->toBounds(); $res['labels'] = LabelModel::loadStaticByBounds($bounds, $zoom, $poiId); } $res['center'] = $vBounds->getCenter()->toWKT(); $res['zoom'] = $zoom; return $res; }