diff --git a/Layout/default/ConstructionConsent/Form.php b/Layout/default/ConstructionConsent/Form.php index e3546467c..91b7cd7cf 100644 --- a/Layout/default/ConstructionConsent/Form.php +++ b/Layout/default/ConstructionConsent/Form.php @@ -154,8 +154,24 @@
- +
+ + + + Vorschau: +
+
+ +
+
+ + +
@@ -222,11 +238,51 @@ placeholder: "Suche nach Straße", allowClear: true }); - $('#adb_strasse_id').on('select2:close', function(e) { - if(!$('#adb_strasse_id').val()) { - $('#new-address-toggle').show(); - } + + $('#plan_adb_hausnummer_id').select2({ + ajax: { + url: '', + data: (params) => { + return { + q: params.term, + do: "findAddress", + project_id: $("#constructionconsentproject_id :selected").val() + } + }, + delay: 250, + dataType: 'json' + }, + minimumInputLength: 2, + placeholder: "Suche nach Adresse", + allowClear: true }); + $('#plan_adb_hausnummer_id').change( async () => { + if(!$("#plan_adb_hausnummer_id").val()) return; + + var building_id = $('#plan_adb_hausnummer_id').val(); + // get plan image preview + + try { + var response = await fetch(' "getRimoPlanPreview"])?>&building_id=' + building_id); + if (!response.ok) { + return false; + } + var resp_json = await response.json(); + var plan_data = resp_json.result; + + var img_mimetype = plan_data.image_mimetype; + var img_base64 = plan_data.image_base64; + + $("#plan_preview").attr("src" ,"data:" + img_mimetype + ";base64," + img_base64); + + } catch (error) { + console.log("Exception fetching plan preview:"); + console.log(error); + return false; + } + + }); + $("#constructionconsentproject_id").change(() => { $("#adb_strasse_id").val("").change(); diff --git a/application/ConstructionConsent/ConstructionConsentController.php b/application/ConstructionConsent/ConstructionConsentController.php index 3a77154a9..e5cbf9873 100644 --- a/application/ConstructionConsent/ConstructionConsentController.php +++ b/application/ConstructionConsent/ConstructionConsentController.php @@ -281,6 +281,15 @@ class ConstructionConsentController extends mfBaseController { case "findStreet": $return = $this->findStreetApi(); break; + case "findAddress": + $return = $this->findAddressApi(); + break; + case "getRimoPlanPreview": + $return = $this->getRimoPlanPreviewApi(); + break; + case "saveRimoPlanPreview": + $return = $this->saveRimoPlanPreviewApi(); + break; default: $this->log->warn(__METHOD__ . ": Called API function '$do' does not exist"); $return = false; @@ -425,4 +434,221 @@ class ConstructionConsentController extends mfBaseController { exit; } + + private function findAddressApi() { + $addresses = []; + $search = trim($this->request->q); + $project_id = $this->request->project_id; + $include_gst = $this->request->include_gst ? $this->request->include_gst : false; + + $scluster_ids = []; + + if($project_id) { + $project = new ConstructionConsentProject($project_id); + if(!$project->id) { + header("Content-Type: application/json"); + echo json_encode(["results" => []]); + exit; + } + + foreach($project->adb_networks as $network) { + $scluster_ids[] = $network->id; + } + } else { + // get all salesclusters + foreach(ADBNetzgebietModel::getAll() as $network) { + $scluster_ids[] = $network->id; + } + } + + $results = []; + + $search_parts = explode(" ", $search); + + $ort_search = $strasse_search = $plz_search = $hausnummer_search = $gst_search = []; + + foreach($search_parts as $p) { + $p = $this->db->escape(trim($p)); + if(!$p) continue; + $ort_search[] = "ortschaft like '$p%'"; + $strasse_search[] = "strasse like '$p%'"; + $plz_search[] = "plz like '%$p%'"; + $hausnummer_search[] = "hausnummer like '%$p%'"; + $gst_search[] = "grund_nr like '%$p%'"; + } + + $where = "1=1"; + if(count($scluster_ids)) { + $where .= " AND netzgebiet_id IN (".implode(', ',$scluster_ids).")"; + } + + if($include_gst) { + $sql = "SELECT * FROM view_hausnummer WHERE $where AND ((".implode(" OR ", $ort_search).") OR (".implode(" OR ", $strasse_search).") OR (".implode(" OR ", $plz_search).") OR (".implode(" OR ", $hausnummer_search).") OR (".implode(" OR ", $gst_search).") ) ORDER BY strasse, LENGTH(hausnummer), hausnummer"; + } else { + $sql = "SELECT * FROM view_hausnummer WHERE $where AND ((".implode(" OR ", $ort_search).") OR (".implode(" OR ", $strasse_search).") OR (".implode(" OR ", $plz_search).") OR (".implode(" OR ", $hausnummer_search).")) ORDER BY strasse, LENGTH(hausnummer), hausnummer"; + } + + + $this->log->debug($sql); + + $adb = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME); + $res = $adb->query($sql); + $this->log->debug("done"); + + if(!$adb->num_rows($res)) { + header("Content-Type: application/json"); + echo json_encode(["results" => []]); + exit; + } + + while($data = $adb->fetch_object($res)) { + $address_string = $data->plz." ".$data->ortschaft.", ".$data->strasse." ".$data->hausnummer; + if($include_gst) { + $address_string .= " | GST: ".$data->grund_nr; + } + $sort_key = $data->plz." ".$data->ortschaft." ".$data->strasse; + + $address = []; + $address['id'] = $data->hausnummer_id; + $address["text"] = $address_string; + $address['sort_key'] = $sort_key; + $addresses[] = $address; + } + + + // sort results by most occurences of search strings + $sort = []; + foreach($addresses as $key => $address) { + $includes_int = false; + $count = 0; + foreach($search_parts as $p) { + $p = $this->db->escape(trim($p)); + if(!$p) continue; + if(is_numeric(($p))) { + $includes_int = true; + if(substr_count(strtolower($address['text']), strtolower($p))) { + $count++; + } + } else { + $count += substr_count(strtolower($address['text']), strtolower($p)); + } + } + unset($address['sort_key']); + //echo $address['text']." $p $count
\n"; + + if($includes_int && (($count + 1) - count($search_parts) ) < 1) { + continue; + } + if(!array_key_exists($count, $sort)) { + $sort[$count] = []; + } + $sort[$count][] = $address; + } + + ksort($sort, SORT_NUMERIC); + $sort = array_reverse($sort, true); + //var_dump($sort);exit; + + foreach($sort as $res) { + foreach($res as $a) { + $results[] = $a; + } + } + + header("Content-Type: application/json"); + echo json_encode(["results" => $results]); + exit; + + } + + private function getRimoPlanPreviewApi() { + $adb_hausnummer_id = $this->request->building_id; + + $hausnummer = new ADBHausnummer($adb_hausnummer_id); + if(!$hausnummer->id) { + return false; + } + + $filename = "consent_plan_map_h{$adb_hausnummer_id}"; + + $bpi_file = PreorderFile::getFirst(["preorder_id" => $this->id, "filename" => $filename]); + if($bpi_file) { + return $bpi_file; + } + + + // get new Borderpoint Image from Mapbox API + $params = [ + "pin" => null, + "gps_lat" => $hausnummer->gps_lat, + "gps_long" => $hausnummer->gps_long, + "zoom" => 19, + "size_x" => 640, + "size_y" => 640, + "style" => "satellite-streets-v12", + "paths" => "", + "access_token" => TT_MAPBOX_TILE_API_TOKEN + ]; + + if($hausnummer->trenches) { + $trenches = json_decode($hausnummer->trenches); + + $params["paths"] = [ + "line_width" => 5, + "line_color" => "ff0000", + "line_opacity" => 1, + "line_fill_color" => "ff0000", + "line_fill_opacity" => 1, + "coords" => $trenches + ]; + } + + $image_content = Mapbox_StaticImageApi::getImageFileContent($params); + if(!$image_content) { + return false; + } + + $fs_filename = "$filename.jpg"; + if(!file_put_contents(MFUPLOAD_FILE_SAVE_PATH."/".TT_CONSTRUCTIONCONSENT_FILE_UPLOAD_SUBFOLDER."/$fs_filename", $image_content)) { + $this->log->error(__METHOD__.": Error saving Borderpoint Static Map Image File"); + return false; + } + + + $file = FileModel::create([ + "name" => "consent_plan_map", + "description" => $adb_hausnummer_id, + "filename" => "$filename.jpg", + "orig_filename" => "$filename.jpg", + "store_filename" => $fs_filename, + "subfolder" => TT_CONSTRUCTIONCONSENT_FILE_UPLOAD_SUBFOLDER, + ]); + if(!$file->save()) { + $this->log->error(__METHOD__.": Error saving File Object"); + return false; + } + + $file->mimetype = $file->getMimetype(); + $file->save(); + + return ["image_mimetype" => $file->mimetype, "image_base64" => base64_encode($image_content)]; + + /*$pf = PreorderFile::create([ + "preorder_id" => $this->id, + "file_id" => $file->id, + "filename" => $filename + ]); + + if(!$pf->save()) { + $this->log->error(__METHOD__.": Error saving PreorderFile Object"); + return false; + }*/ + + //return $pf; + } + + private function saveRimoPlanPreviewApi() { + $adb_hausnummer_id = $this->request->building_id; + $consent_id = $this->request->constructionconsent_id; + } } \ No newline at end of file diff --git a/lib/Mapbox/StaticImageApi.php b/lib/Mapbox/StaticImageApi.php index bccc7a65a..1b7036a76 100644 --- a/lib/Mapbox/StaticImageApi.php +++ b/lib/Mapbox/StaticImageApi.php @@ -11,6 +11,7 @@ class Mapbox_StaticImageApi { $size_y = $params["size_y"]; $style = $params["style"]; $pin = $params["pin"]; + $paths = $params["paths"]; $pin_part = ""; @@ -23,12 +24,50 @@ class Mapbox_StaticImageApi { $pin_color = $pin["color"]; $pin_icon = $pin["icon"]; - $pin_part .= "/pin-$pin_size"; + $pin_part .= "pin-$pin_size"; if($pin_icon) $pin_part .= "-$pin_icon"; $pin_part .= "+$pin_color($pin_gps_long,$pin_gps_lat)"; } - $url .= "$pin_part/$gps_long,$gps_lat,$zoom/{$size_x}x{$size_y}?access_token=$access_token"; + $path_parts = []; + if(is_array($paths) && count($paths)) { + $path_stroke_width = $paths["line_width"]; + $path_stroke_color = $paths["line_color"]; + $path_stroke_opacity = $paths["line_opacity"]; + $path_fill_color = $paths["line_fill_color"]; + $path_fill_opacity = $paths["line_fill_opacity"]; + + foreach($paths["coords"] as $path) { + if(!is_array($path)) { + mfLoghandler::singleton()->debug("path not array: ".print_r($path, true)); + continue; + } + + $path_enc_polyline = self::encodeCoordArrayToPolyline($path); + if(!$path_enc_polyline) continue; + + $path_parts[] = "path-$path_stroke_width+$path_stroke_color-$path_stroke_opacity+$path_fill_color-$path_fill_opacity($path_enc_polyline)"; + } + } + + // build url + $url_opt_parts = []; + if($pin_part) $url_opt_parts[] = $pin_part; + + if(count($path_parts)) { + foreach($path_parts as $path_part) { + $url_opt_parts[] = $path_part; + } + } + + if(is_array($url_opt_parts)) { + $url .= "/".implode(",", $url_opt_parts); + } + + $url .= "/auto/{$size_x}x{$size_y}?access_token=$access_token"; + + mfLoghandler::singleton()->debug($url); + //exit; $ctx_opts = [ 'http' => [ @@ -47,4 +86,43 @@ class Mapbox_StaticImageApi { return $response; } + + public static function encodeCoordArrayToPolyline($coords, $precision = 5) { + //if(!is_array($coords)) return false; + + $points = []; + array_walk_recursive( + $coords, + function ($current) use (&$points) { + $points[] = $current; + } + ); + + mfLoghandler::singleton()->debug(__METHOD__.": flattened path: ".print_r($points, true)); + + $encodedString = ''; + $index = 0; + $previous = array(0,0); + foreach ( $points as $number ) { + $number = (float)($number); + $number = (int)round($number * pow(10, $precision)); + $diff = $number - $previous[$index % 2]; + $previous[$index % 2] = $number; + $number = $diff; + $index++; + $number = ($number < 0) ? ~($number << 1) : ($number << 1); + $chunk = ''; + while ( $number >= 0x20 ) { + $chunk .= chr((0x20 | ($number & 0x1f)) + 63); + $number >>= 5; + } + $chunk .= chr($number + 63); + $encodedString .= $chunk; + } + + mfLoghandler::singleton()->debug(__METHOD__.": encoded polyline: $encodedString"); + + + return str_replace("?", "%3f", $encodedString); + } } \ No newline at end of file diff --git a/scripts/adb-rimo-import/rimo-import.php b/scripts/adb-rimo-import/rimo-import.php index 95967500d..59d850d8e 100755 --- a/scripts/adb-rimo-import/rimo-import.php +++ b/scripts/adb-rimo-import/rimo-import.php @@ -680,7 +680,7 @@ foreach ($clusters as $cluster_data) { if($wo_home_external_id) { $wo_home = \ADBWohneinheitModel::getFirst(["extref" => $wo_home_external_id]); if($wo_home != $wo->adb_wohneinheit_id) { - $addressErrors[] = "Wohneinheit für Workorder ".$wo->name." hat sich geändert von ".$wo->adb_wohneinheit_id." auf ".$wo_home->extref." (aber wurde nicht im Tool übernommen)"; + $addressErrors[] = "Wohneinheit für Workorder ".$wo->rimo_name." hat sich geändert von ".$wo->adb_wohneinheit_id." auf ".$wo_home->extref." (aber wurde nicht im Tool übernommen)"; } } else { $addressErrors[] = "Wohneinheit für Workorder ".$wo->name." ist jetzt leer";