ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Web; using System.Web.Http; using Newtonsoft.Json; using SiteSelection.Properties; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.Routing; using ThinkGeo.MapSuite.WebApiEdition; namespace SiteSelection.Controllers { [RoutePrefix("SiteSelection")] public class SiteSelectionController : ApiController { private static Dictionary<string, Collection<string>> poiTypes; private static LayerOverlay poiOverlay; private static RoutingEngine routingEngine; static SiteSelectionController() { // Create the static POI Overlay. poiOverlay = new LayerOverlay(); ManagedProj4Projection wgs84ToMercatorProj4Projection = new ManagedProj4Projection(); wgs84ToMercatorProj4Projection.InternalProjectionParametersString = Proj4Projection.GetWgs84ParametersString(); wgs84ToMercatorProj4Projection.ExternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString(); wgs84ToMercatorProj4Projection.Open(); ShapeFileFeatureLayer friscoBoundaryLayer = new ShapeFileFeatureLayer(InternalHelper.GetFullPath(@"App_Data\CityLimitPolygon.shp")); friscoBoundaryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new AreaStyle(new GeoPen(GeoColor.SimpleColors.White, 5.5f), new GeoSolidBrush(GeoColor.SimpleColors.Transparent))); friscoBoundaryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new AreaStyle(new GeoPen(GeoColor.SimpleColors.Red, 1.5f) { DashStyle = LineDashStyle.Dash }, new GeoSolidBrush(GeoColor.SimpleColors.Transparent))); friscoBoundaryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; friscoBoundaryLayer.FeatureSource.Projection = wgs84ToMercatorProj4Projection; poiOverlay.Layers.Add("friscoBoundary", friscoBoundaryLayer); ShapeFileFeatureLayer hotelsLayer = new ShapeFileFeatureLayer(InternalHelper.GetFullPath(@"App_Data\POIs\Hotels.shp")); hotelsLayer.Transparency = 200f; hotelsLayer.ZoomLevelSet.ZoomLevel10.DefaultPointStyle = new PointStyle(new GeoImage(InternalHelper.GetFullPath(@"Images\Hotel.png"))); hotelsLayer.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; hotelsLayer.FeatureSource.Projection = wgs84ToMercatorProj4Projection; poiOverlay.Layers.Add("hotelsLayer", hotelsLayer); ShapeFileFeatureLayer medicalFacilitesLayer = new ShapeFileFeatureLayer(InternalHelper.GetFullPath(@"App_Data\POIs\Medical_Facilities.shp")); medicalFacilitesLayer.Transparency = 200f; medicalFacilitesLayer.ZoomLevelSet.ZoomLevel10.DefaultPointStyle = new PointStyle(new GeoImage(InternalHelper.GetFullPath(@"Images\DrugStore.png"))); medicalFacilitesLayer.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; medicalFacilitesLayer.FeatureSource.Projection = wgs84ToMercatorProj4Projection; poiOverlay.Layers.Add("Medical Facilites", medicalFacilitesLayer); ShapeFileFeatureLayer publicFacilitesLayer = new ShapeFileFeatureLayer(InternalHelper.GetFullPath(@"App_Data\POIs\Public_Facilities.shp")); publicFacilitesLayer.Transparency = 200f; publicFacilitesLayer.ZoomLevelSet.ZoomLevel10.DefaultPointStyle = new PointStyle(new GeoImage(InternalHelper.GetFullPath(@"Images\public_facility.png"))); publicFacilitesLayer.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; publicFacilitesLayer.FeatureSource.Projection = wgs84ToMercatorProj4Projection; poiOverlay.Layers.Add(publicFacilitesLayer); ShapeFileFeatureLayer restaurantsLayer = new ShapeFileFeatureLayer(InternalHelper.GetFullPath(@"App_Data\POIs\Restaurants.shp")); restaurantsLayer.Transparency = 200f; restaurantsLayer.ZoomLevelSet.ZoomLevel10.DefaultPointStyle = new PointStyle(new GeoImage(InternalHelper.GetFullPath(@"Images\restaurant.png"))); restaurantsLayer.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; restaurantsLayer.FeatureSource.Projection = wgs84ToMercatorProj4Projection; poiOverlay.Layers.Add("Restaurants", restaurantsLayer); ShapeFileFeatureLayer schoolsLayer = new ShapeFileFeatureLayer(InternalHelper.GetFullPath(@"App_Data\POIs\Schools.shp")); schoolsLayer.Transparency = 200f; schoolsLayer.ZoomLevelSet.ZoomLevel10.DefaultPointStyle = new PointStyle(new GeoImage(InternalHelper.GetFullPath(@"Images\school.png"))); schoolsLayer.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; schoolsLayer.FeatureSource.Projection = wgs84ToMercatorProj4Projection; poiOverlay.Layers.Add("Schools", schoolsLayer); // Create the Routine Engine. string streetShapeFilePathName = InternalHelper.GetFullPath(@"App_Data\street.shp"); string streetRtgFilePathName = Path.ChangeExtension(streetShapeFilePathName, ".rtg"); RtgRoutingSource routingSource = new RtgRoutingSource(streetRtgFilePathName); FeatureSource featureSource = new ShapeFileFeatureSource(streetShapeFilePathName); featureSource.Projection = wgs84ToMercatorProj4Projection; routingEngine = new RoutingEngine(routingSource, featureSource); routingEngine.GeographyUnit = GeographyUnit.Meter; // Initialise categories poiTypes = new Dictionary<string, Collection<string>>(); foreach (string layerId in new string[] { "Hotels", "Medical Facilites", "Restaurants", "Schools" }) { poiTypes.Add(layerId, GetPoiSubTypes(poiOverlay, layerId)); } } [Route("GetCategories")] public string GetCategories() { // Return the categories in JSON to client side. return JsonConvert.SerializeObject(poiTypes); } [Route("baselayer/{z}/{x}/{y}")] public HttpResponseMessage GetBaseLayerTile(int z, int x, int y) { return GenerateTile(z, x, y, poiOverlay); } [Route("resultlayer/{z}/{x}/{y}")] public HttpResponseMessage GetResultLayerTile(int z, int x, int y) { return GenerateTile(z, x, y, GetResultOverlay()); } [Route("Search")] [HttpPost] public string Search([FromBody] string parameterString) { Dictionary<string, string> parameters = JsonConvert.DeserializeObject<Dictionary<string, string>>(parameterString); string[] searchPointLatLng = parameters["searchPoint"].Split(','); PointShape searchPoint = InternalHelper.ConvertToSphericalMercator<PointShape>(new PointShape(double.Parse(searchPointLatLng[0]), double.Parse(searchPointLatLng[1]))); string result = JsonConvert.SerializeObject(new { status = "2", message = "out of restriction area" }); // check if the clicked point is in valid area (Frisco County) FeatureLayer friscoLayer = (FeatureLayer)poiOverlay.Layers["friscoBoundary"]; friscoLayer.Open(); if (friscoLayer.QueryTools.GetFeaturesContaining(searchPoint, ReturningColumnsType.NoColumns).Any()) { // Calculate the service area/buffer area and display it on the map LayerOverlay resultOverlay = GetResultOverlay(); InMemoryFeatureLayer serviceAreaLayer = (InMemoryFeatureLayer)resultOverlay.Layers["serviceArea"]; serviceAreaLayer.Open(); serviceAreaLayer.InternalFeatures.Clear(); if (parameters["searchMode"] == "serviceArea") { int drivingTimeInMinutes = Convert.ToInt32(parameters["driveTime"], CultureInfo.InvariantCulture); serviceAreaLayer.InternalFeatures.Add(new Feature(routingEngine.GenerateServiceArea(searchPoint, new TimeSpan(0, drivingTimeInMinutes, 0), 100, GeographyUnit.Meter))); } else { DistanceUnit distanceUnit = parameters["distanceUnit"] == "Mile" ? DistanceUnit.Mile : DistanceUnit.Kilometer; double distanceBuffer = Convert.ToDouble(parameters["distanceBuffer"], CultureInfo.InvariantCulture); serviceAreaLayer.InternalFeatures.Add(new Feature(searchPoint.Buffer(distanceBuffer, 40, GeographyUnit.Meter, distanceUnit))); } // Search the Pois in calculated service area and display them on map InMemoryFeatureLayer highlightFeatureLayer = (InMemoryFeatureLayer)resultOverlay.Layers["HighlightFeatureLayer"]; highlightFeatureLayer.Open(); highlightFeatureLayer.InternalFeatures.Clear(); ShapeFileFeatureLayer poiLayer = (ShapeFileFeatureLayer)(poiOverlay.Layers[parameters["category"]); Collection<Feature> featuresInServiceArea = poiLayer.QueryTools.GetFeaturesWithin(serviceAreaLayer.InternalFeatures[0].GetShape(), ReturningColumnsType.AllColumns); List<Feature> filteredQueryFeatures = FilterFeaturesByQueryConfiguration(featuresInServiceArea, parameters["category"], parameters["subCategory"].Replace(">~", ">=")); if (filteredQueryFeatures.Any()) { Collection<object> jsonFeatures = new Collection<object>(); foreach (Feature feature in filteredQueryFeatures) { highlightFeatureLayer.InternalFeatures.Add(feature); PointShape latlng = InternalHelper.ConvertToWgs84<PointShape>(feature.GetShape()); jsonFeatures.Add(new { name = feature.ColumnValues["NAME"], point = string.Format("{0},{1}", latlng.Y, latlng.X) }); } result = JsonConvert.SerializeObject(new { status = "0", message = "has features", features = jsonFeatures }); } else { result = JsonConvert.SerializeObject(new { status = "1", message = "without features" }); } } return result; } [Route("ClearSearch")] [HttpPost] public void Clear() { LayerOverlay resultOverlay = GetResultOverlay(); foreach (Layer layer in resultOverlay.Layers) { layer.Open(); ((InMemoryFeatureLayer)layer).InternalFeatures.Clear(); layer.Close(); } } private LayerOverlay GetResultOverlay() { // Create the result overlay and put it into the session. LayerOverlay resultOverlay = HttpContext.Current.Session["resultOverlay"] as LayerOverlay; if (resultOverlay == null) { resultOverlay = new LayerOverlay(); InMemoryFeatureLayer serviceAreaLayer = new InMemoryFeatureLayer(); serviceAreaLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(new GeoColor(120, GeoColor.FromHtml("#33a8e1")), GeoColor.FromHtml("#428ce3"), 2, LineDashStyle.Solid); serviceAreaLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; InMemoryFeatureLayer highlightFeatureLayer = new InMemoryFeatureLayer(); highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(new GeoImage(InternalHelper.GetFullPath(@"Images\selectedHalo.png"))); highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; resultOverlay.Layers.Add("serviceArea", serviceAreaLayer); resultOverlay.Layers.Add("HighlightFeatureLayer", highlightFeatureLayer); HttpContext.Current.Session["resultOverlay"] = resultOverlay; } return resultOverlay; } private static Collection<string> GetPoiSubTypes(LayerOverlay queryingOverlay, string poiType) { Collection<string> poiSubTypes = new Collection<string>(); poiSubTypes.Add("All"); string columnName = InternalHelper.GetDbfColumnByPoiType(poiType); if (columnName.Equals("Hotels")) { poiSubTypes.Add("1 ~ 50"); poiSubTypes.Add("50 ~ 100"); poiSubTypes.Add("100 ~ 150"); poiSubTypes.Add("150 ~ 200"); poiSubTypes.Add("200 ~ 300"); poiSubTypes.Add("300 ~ 400"); poiSubTypes.Add("400 ~ 500"); poiSubTypes.Add(">= 500"); } else { ShapeFileFeatureLayer inMemoryFeatureLayer = (ShapeFileFeatureLayer)queryingOverlay.Layers[poiType]; inMemoryFeatureLayer.Open(); IEnumerable<string> distinctColumnValues = inMemoryFeatureLayer.FeatureSource.GetDistinctColumnValues(columnName).Select(v => v.ColumnValue); foreach (string distinctColumnValue in distinctColumnValues) { poiSubTypes.Add(distinctColumnValue); } } return poiSubTypes; } private List<Feature> FilterFeaturesByQueryConfiguration(Collection<Feature> allFeatures, string category, string subCategory) { if (subCategory.Equals("All")) { return allFeatures.ToList(); } else if (!category.Equals("Hotels")) { return allFeatures.Where(f => f.ColumnValues[InternalHelper.GetDbfColumnByPoiType(category)] == subCategory).ToList(); } else { string queriedColumn = InternalHelper.GetDbfColumnByPoiType(category); List<Feature> queriedPois = new List<Feature>(); foreach (Feature feature in allFeatures) { int rooms = int.Parse(feature.ColumnValues[queriedColumn], CultureInfo.InvariantCulture); string[] values = subCategory.Split('~'); if (values.Length >= 2) { if (int.Parse(values[0], CultureInfo.InvariantCulture) <= rooms && int.Parse(values[1], CultureInfo.InvariantCulture) >= rooms) { queriedPois.Add(feature); } } else if (values.Length == 1) { int maxValue = int.Parse(values[0].TrimStart(new[] { '>', '=', ' ' }), CultureInfo.InvariantCulture); if (rooms > maxValue) { queriedPois.Add(feature); } } } return queriedPois; } } private static HttpResponseMessage GenerateTile(int z, int x, int y, LayerOverlay overlay) { using (Bitmap bitmap = new Bitmap(256, 256)) { GdiPlusGeoCanvas geoCanvas = new GdiPlusGeoCanvas(); RectangleShape boundingBox = WebApiExtentHelper.GetBoundingBoxForXyz(x, y, z, GeographyUnit.Meter); geoCanvas.BeginDrawing(bitmap, boundingBox, GeographyUnit.Meter); overlay.Draw(geoCanvas); geoCanvas.EndDrawing(); MemoryStream ms = new MemoryStream(); bitmap.Save(ms, ImageFormat.Png); HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.OK); msg.Content = new ByteArrayContent(ms.ToArray()); msg.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png"); return msg; } } } }
using System; using System.Collections.Generic; using System.IO; using System.Reflection; using ThinkGeo.MapSuite.Core; namespace SiteSelection { public static class InternalHelper { private static Dictionary<string, string> poiColumns; private static ManagedProj4Projection projection; public static string GetDbfColumnByPoiType(string poiCategory) { if (poiColumns == null) { poiColumns = new Dictionary<string, string>(); poiColumns.Add("Hotels", "Hotels"); poiColumns.Add("Medical Facilites", "TYPE"); poiColumns.Add("Restaurants", "FoodType"); poiColumns.Add("Schools", "TYPE"); } return poiColumns[poiCategory]; } public static string GetFullPath(string fileName) { Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase); string rootDirectory = Path.GetDirectoryName(Path.GetDirectoryName(uri.LocalPath)); return Path.Combine(rootDirectory, fileName); ; } public static T ConvertToWgs84<T>(BaseShape baseShape) where T : BaseShape { InitializeProjection(); return projection.ConvertToInternalProjection(baseShape) as T; } public static T ConvertToSphericalMercator<T>(BaseShape baseShape) where T : BaseShape { InitializeProjection(); return projection.ConvertToExternalProjection(baseShape) as T; } private static void InitializeProjection() { if (projection == null) { projection = new ManagedProj4Projection(); projection.InternalProjectionParametersString = Proj4Projection.GetWgs84ParametersString(); projection.ExternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString(); projection.Open(); } } } }
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Site Selection</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="author" content="ThinkGeo" /> <link rel="apple-touch-icon" href="desktop.png" /> <meta name="apple-mobile-web-app-title" content="Site Selection" /> <link href="favicon.ico" rel="shortcut icon" type="Images/x-icon" /> <link href="Content/leaflet.css" rel="stylesheet" /> <link href="Content/bootstrap.min.css" rel="stylesheet" /> <link href="Content/Site.css" rel="stylesheet" /> </head> <body> <div id="map"> </div> <div id="message"></div> <div id="loadingImage"> <img src="Images/ajax-loader.gif" /> </div> <div id="legend"> <img src="Images/legend.png" /> </div> <div id="left-panel"> <div class="panel-header"> <span class="title">Result List</span> </div> <div class="panel-content"> <div id="div-resultlist"> <table id="result-table" class="table table-triped table-bordered"> <tr> <td></td> <td>Name </td> </tr> </table> </div> </div> </div> <div class="centroid"> <div id="edit-panel"> <div class="edit-panel-header"> <span id="settingTitle">Settings of site selection</span> </div> <div id="div-setting" class="edit-content"> <div class="edit-body"> Highlight points of this type <select id="sltCategory"> </select> <select id="sltCategorySubtype"> </select> Area Type <select id="sltSearchMode"> <option value="serviceArea">Service Area</option> <option value="bufferedArea">Buffered Area</option> </select> <div id="divService"> <span class="valueLabel">Service Area in</span> <input type="text" id="tbxServiceArea" class="valueTxt" value="5" /><span class="valueLabel"> Minutes Driving</span> </div> <div id="divBuffer" style="display: none;"> <span class="valueLabel">Buffer Distance:</span> <input type="text" id="tbxDistance" class="valueTxt" value="2" /> <select id="sltDistanceUnit" style="width: 100px;"> <option value="Mile">Mile</option> <option value="Kilometer">Kilometer</option> </select> </div> </div> </div> <div class="edit-foot"> <a id="btnSettingCancel" href="#" class="btn btn-default" role="button">Cancel</a> <a id="btnSettingSave" href="#" class="btn btn-primary" role="button">Save</a> </div> </div> </div> <script src="Scripts/jquery-1.11.1.min.js"></script> <script src="Scripts/leaflet.js"></script> <script src="thinkgeo.leaflet.js"></script> <script> var map, searchPoint, resultLayer, markers, searchPointIcon, trackMode = 'plot'; var defaultSetting = { lng: -96.809983627817, lat: 33.128303417665, category: 'Restaurants', subCategory: 'All', searchMode: 'serviceArea', driveTime:5 }; $(function () { // Initialize the POI categories and its sub-type categories $.get(L.Util.getRootPath() + "/SiteSelection/GetCategories/", function (response) { var categoies = JSON.parse(response); $.each(categoies, function (key) { $('#sltCategory').append($("<option/>", { value: key, text: key })); }); $("#sltCategory").change(function () { var selectValue = $("#sltCategory").val(); var selectedCategories; if (categoies.hasOwnProperty(selectValue)) { selectedCategories = categoies[selectValue]; } $('#sltCategorySubtype').empty(); for (var i = 0; i < selectedCategories.length; i++) { $('#sltCategorySubtype').append($("<option/>", { value: selectedCategories[i], text: selectedCategories[i] })); } }); var setting = defaultSetting; searchPoint = new L.LatLng(setting.lat, setting.lng); L.marker([setting.lat,|setting.lng], { icon: searchPointIcon }).addTo(markers); $("#sltCategory").val(setting.category).trigger('change'); $("#sltCategorySubtype").val(setting.subCategory); $("#sltSearchMode").val(setting.searchMode).trigger('change'); if (setting.driveTime) { $("#tbxServiceArea").val(setting.driveTime); } if (setting.bufferDistance) { $("#tbxServiceArea").val(setting.bufferDistance); } if (setting.sltDistanceUnit) { $("#tbxServiceArea").val(setting.distanceUnit); } applySearch(); }); // Initialize the map. map = L.map('map', { center: [33.1279394892519,|-96.8008536874563], zoom: 14 }); L.control.scale().addTo(map); // Add the marker layer for search location. markers = new L.FeatureGroup(); map.addLayer(markers); searchPointIcon = L.icon({ iconUrl: 'Images/drawPoint.png', iconSize: [32,|32], iconAnchor: [16,|32] }); // Added WorldMapKit Online as the background map. L.tileLayer.wms('http://{s}.thinkgeo.com/CachedWMSServer/WmsServer.axd', { subdomains: ['worldmapkit1',|'worldmapkit2', 'worldmapkit3', 'worldmapkit4', 'worldmapkit5', 'worldmapkit6'], layers: 'OSMWorldMapKitLayer', format: 'image/png', styles: 'WorldMapKitDefaultStyle', version: '1.1.1', attribution: '<a href="http://thinkgeo.com/map-suite-developer-gis/world-map-kit-sdk/">ThinkGeo</a> | © <a href="http://osm.org/copyright">OpenStreetMap</a> contributors ' }).addTo(map); // Add POI layer. L.tileLayer(L.Util.getRootPath() + '/SiteSelection/baselayer/{z}/{x}/{y}').addTo(map); // Create a layer which requests the tiles from the webapi controller action resultLayer = L.dynamicLayer(L.Util.getRootPath() + '/SiteSelection/resultlayer/{z}/{x}/{y}').addTo(map); resultLayer.on('loading', function () { $('#loadingImage').show(); }) resultLayer.on('load', function () { $('#loadingImage').hide(); }) // Add image controls for pan, plot, settings etc. L.imageButtons({ imgs: [ | { src: 'Images/pan.png', id: 'btnPan', title: 'Pan the map', callback: function (e) { trackMode = 'pan'; $(map.getContainer()).css("cursor", "pointer"); $('#btnPlot').removeClass('active'); $(e.target).addClass('active'); } }, { src: 'Images/plot.png', id: 'btnPlot', title: 'Plot a point', css: 'active', callback: function (e) { trackMode = 'plot'; $(map.getContainer()).css("cursor", "crosshair"); $('#btnPan').removeClass('active'); $(e.target).addClass('active'); } }, { src: 'Images/clear.png', id: 'btnClear', title: 'clear', callback: function () { $.post(L.Util.getRootPath() + "SiteSelection/ClearSearch", function () { searchPoint = null; markers.clearLayers(); resultLayer.redraw(); // Remove all the lines except the header $("#result-table tr:gt(0)").remove(); }); } }, { src: 'Images/gear.png', id: 'btnSetting', title: 'setting', callback: function () { showSettingDlg(); } } ] }).addTo(map); L.imageButtons({ imgs: [ | { src: 'Images/more.png', id: 'btnMore', title: 'Show Details', callback: function () { showResultDlg(); } }] }).addTo(map); // Function for plotting a point on the map and do a query based on the clicked point. $(map.getContainer()).css("cursor", "crosshair"); map.on("click", function (e) { if (trackMode == 'plot') { if (listViewHidden()) { searchPoint = e.latlng; markers.clearLayers(); L.marker([e.latlng.lat,|e.latlng.lng], { icon: searchPointIcon }).addTo(markers); applySearch(); } } }); $("html").click(function () { $('#left-panel').animate({ 'left': -$('#left-panel').width() + 'px' }); }); var listViewHidden = function () { return ($("#left-panel").css("left") != "0px"); } $("#sltSearchMode").change(function (e) { if ($("#sltSearchMode").val() == 'bufferedArea') { $("#divBuffer").show(); $("#divService").hide(); } else { $("#divBuffer").hide(); $("#divService").show(); } }); $("#btnSettingCancel").click(function () { hideSettingDlg(); }); $("#btnSettingSave").click(function () { applySearch(); }); var applySearch = function () { hideSettingDlg(); if (!searchPoint) { return; } var category = $("#sltCategory").val();; var subCategory = $('#sltCategorySubtype').val().replace(">=", ">~"); var searchMode = $("#sltSearchMode").val(); var args = { "category": category, "subCategory": subCategory, "searchMode": searchMode, "searchPoint": searchPoint.lng + "," + searchPoint.lat }; if (searchMode == "serviceArea") { args["driveTime"] = $("#tbxServiceArea").val(); } else { args["distanceBuffer"] = $("#tbxDistance").val(); args["distanceUnit"] = $("#sltDistanceUnit").val(); } $.post(L.Util.getRootPath() + "SiteSelection/Search", { //: JSON.stringify(args) }, function (res) { resultLayer.redraw(); $("#result-table tr:gt(0)").remove(); var data = JSON.parse(res); if (data.status == 2) { $("#message").html("Please note that this sample map is only able to analyze service areas within the Frisco, TX city limits, <br\>which are indicated by a dashed red line. Click inside that boundary for best results. "); $("#message").show().delay(5000).fadeOut(); } if (data.status == 1) { $("#message").text("No results found."); $("#message").show().delay(5000).fadeOut(); } if (data.status == 0) { bindSearchResult(data.features); } }); } }); // Functions for displaying query result to grid table. function bindSearchResult(queryItems) { // Remove all the lines except the header $("#result-table tr:gt(0)").remove(); // Display data in the Grid table for (var i = 0; i < queryItems.length; i++) { var name = queryItems[i].name; var position = queryItems[i].point; var newRow = $("<tr>"); newRow.append('<td><a style="width:14px;display:block;"><img alt="Search" title="Zoom to sepcified POI" src="Images/find.png" onclick="zoomToPoi(' + position.split(',')[0] + ',' + position.split(',')[1] + ')" /></a></td>'); newRow.append("<td>" + name + "</td>"); $("#result-table > tbody:last").append(newRow); } } function zoomToPoi(lat, lng) { map.setView(L.latLng(lat, lng), 16); } /* Setting dialog events*/ function showSettingDlg() { this.bgmask = L.DomUtil.create('div', 'bg-mask'); $('body').append(this.bgmask); $('#edit-panel').slideToggle("fast"); } function hideSettingDlg() { if ($('#edit-panel').is(':visible')) { $('.bg-mask').remove(); $('#edit-panel').slideToggle("fast"); } } function showResultDlg() { $('#left-panel').animate({ 'left': '0px' }); } </script> </body> </html>
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Site Selection</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="author" content="ThinkGeo" /> <link rel="apple-touch-icon" href="desktop.png" /> <meta name="apple-mobile-web-app-title" content="Site Selection" /> <link href="favicon.ico" rel="shortcut icon" type="Images/x-icon" /> <link href="Content/ol.css" rel="stylesheet" /> <link href="Content/bootstrap.min.css" rel="stylesheet" /> <link href="Content/thinkgeo.openlayers.css" rel="stylesheet" /> <link href="Content/Site.css" rel="stylesheet" /> </head> <body> <div id="map"> </div> <div id="message"></div> <div id="loadingImage"> <img src="Images/ajax-loader.gif" /> </div> <div id="legend"> <img src="Images/legend.png" /> </div> <div id="left-panel"> <div class="panel-header"> <span class="title">Result List</span> </div> <div class="panel-content"> <div id="div-resultlist"> <table id="result-table" class="table table-triped table-bordered"> <tr> <td></td> <td>Name </td> </tr> </table> </div> </div> </div> <div class="centroid"> <div id="edit-panel"> <div class="edit-panel-header"> <span id="settingTitle">Settings of site selection</span> </div> <div id="div-setting" class="edit-content"> Highlight points of this type <select id="sltCategory"> </select> <select id="sltCategorySubtype"> </select> Area Type <select id="sltSearchMode"> <option value="serviceArea">Service Area</option> <option value="bufferedArea">Buffered Area</option> </select> <div id="divService"> <span class="valueLabel">Service Area in</span> <input type="text" id="tbxServiceArea" class="valueTxt" value="5" /><span class="valueLabel"> Minutes Driving</span> </div> <div id="divBuffer" style="display: none;"> <span class="valueLabel">Buffer Distance:</span> <input type="text" id="tbxDistance" class="valueTxt" value="2" /> <select id="sltDistanceUnit" style="width: 200px;"> <option value="Mile">Mile</option> <option value="Kilometer">Kilometer</option> </select> </div> </div> <div class="edit-foot"> <a id="btnSettingCancel" href="#" class="btn btn-default" role="button">Cancel</a> <a id="btnSettingSave" href="#" class="btn btn-primary" role="button">Save</a> </div> </div> </div> <script src="Scripts/jquery-1.11.1.min.js"></script> <script src="Scripts/ol.js"></script> <script src="thinkgeo.openlayers.js"></script> <script> var map, resultLayer, searchPoint, trackMode = 'plot', markerLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: [] }) });; var markerFeature; var defaultSetting = { lng: -96.809983627817, lat: 33.128303417665, category: 'Restaurants', subCategory: 'All', searchMode: 'serviceArea', driveTime: 5 }; $(function () { // Initialize the POI categories and its sub-type categories $.get(getRootPath() + "/SiteSelection/GetCategories/", function (response) { var categoies = JSON.parse(response); $.each(categoies, function (key) { $('#sltCategory').append($("<option/>", { value: key, text: key })); }); $("#sltCategory").change(function () { var selectValue = $("#sltCategory").val(); var selectedCategories; if (categoies.hasOwnProperty(selectValue)) { selectedCategories = categoies[selectValue]; } $('#sltCategorySubtype').empty(); for (var i = 0; i < selectedCategories.length; i++) { $('#sltCategorySubtype').append($("<option/>", { value: selectedCategories[i], text: selectedCategories[i] })); } }); var setting = defaultSetting; var x = parseFloat(setting.lng); var y = parseFloat(setting.lat); searchPoint = ol.proj.transform([x,|y], 'EPSG:4326', 'EPSG:3857'); $("#sltCategory").val(setting.category).trigger('change'); $("#sltCategorySubtype").val(setting.subCategory); $("#sltSearchMode").val(setting.searchMode).trigger('change'); if (setting.driveTime) { $("#tbxServiceArea").val(setting.driveTime); } if (setting.bufferDistance) { $("#tbxServiceArea").val(setting.bufferDistance); } if (setting.sltDistanceUnit) { $("#tbxServiceArea").val(setting.distanceUnit); } applySearch(); }); // Create the openlayers-map map = new ol.Map({ target: 'map', controls: ol.control.defaults({ attribution: false }).extend( [new|ol.control.Attribution({ collapsible: false })]), view: new ol.View({ center: [-10775821.740841813,|3912298.129520194], zoom: 14 }) }); // Add thinkgeo map var worldmapkitlayer = new ol.layer.Tile({ source: new ol.source.TileWMS(({ urls: ['http://worldmapkit1.thinkgeo.com/CachedWMSServer/WmsServer.axd', | 'http://worldmapkit2.thinkgeo.com/CachedWMSServer/WmsServer.axd', 'http://worldmapkit3.thinkgeo.com/CachedWMSServer/WmsServer.axd', 'http://worldmapkit4.thinkgeo.com/CachedWMSServer/WmsServer.axd', 'http://worldmapkit5.thinkgeo.com/CachedWMSServer/WmsServer.axd', 'http://worldmapkit6.thinkgeo.com/CachedWMSServer/WmsServer.axd'], params: { 'LAYERS': 'OSMWorldMapKitLayer', 'VERSION': '1.1.1' }, attributions: [new|ol.Attribution({ html: '<a href="http://thinkgeo.com/map-suite-developer-gis/world-map-kit-sdk/">ThinkGeo</a> | © <a href="http://osm.org/copyright">OpenStreetMap</a> contributors <a href="http://www.openstreetmap.org/copyright">ODbL</a>' })] })) }); map.addLayer(worldmapkitlayer); // Add POI layer. map.addLayer(new ol.layer.Tile({ source: new ol.source.XYZ({ url: getRootPath() + "/SiteSelection/baselayer/{z}/{x}/{y}", maxZoom: 19 }) })); // Create a layer which requests the tiles from the webapi controller action var resultSource = new ol.source.XYZ({ url: getRootPath() + "/SiteSelection/resultlayer/{z}/{x}/{y}", maxZoom: 19 }); resultSource.tileLoadFunction = function (imageTile, src) { imageTile.getImage().src = src + '?t=' + new Date().getTime();; }; map.addLayer(new ol.layer.Tile({ source: resultSource })); // add marker layer. markerLayer.getSource().clear(); markerFeature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.transform([defaultSetting.lng,|defaultSetting.lat], 'EPSG:4326', 'EPSG:3857')) }); markerFeature.setStyle( new ol.style.Style({ image: new ol.style.Icon(({ anchor: [0.5,|32], anchorXUnits: 'fraction', anchorYUnits: 'pixels', opacity: 0.75, src: 'Images/drawPoint.png' })) })); markerLayer.getSource().addFeature(markerFeature); map.addLayer(markerLayer); // Add image controls for pan, plot, settings etc. var imgControls = new app.ImagesControl({ imgs: [ | { src: 'Images/pan.png', id: 'btnPan', title: 'Pan the map', callback: function (e) { trackMode = 'pan'; $(map.getViewport()).css("cursor", "pointer"); $('#btnPlot').removeClass('active'); $(e.target).addClass('active'); } }, { src: 'Images/plot.png', id: 'btnPlot', title: 'Plot a point', css: 'active', callback: function (e) { trackMode = 'plot'; $(map.getViewport()).css("cursor", "crosshair"); $('#btnPan').removeClass('active'); $(e.target).addClass('active'); } }, { src: 'Images/clear.png', id: 'btnClear', title: 'clear', callback: function () { $.post(getRootPath() + "SiteSelection/ClearSearch", function () { markerFeature.setGeometry(new ol.geom.Point([0,0])); resultSource.setUrl(getRootPath() + "/SiteSelection/resultlayer/{z}/{x}/{y}"); // Remove all the lines except the header $("#result-table tr:gt(0)").remove(); }); } }, { src: 'Images/gear.png', id: 'btnSetting', title: 'setting', callback: function () { showSettingDlg(); } }, { src: 'Images/more.png', id: 'btnMore', title: 'Show Details', callback: function () { showResultDlg(); } } ] }); map.addControl(imgControls); // Function for plotting a point on the map and do a query based on the clicked point. $(map.getViewport()).css("cursor", "crosshair"); map.on("click", function (e) { if (trackMode == 'plot') { if (listViewHidden()) { searchPoint = e.coordinate; markerFeature.setGeometry(new ol.geom.Point(e.coordinate)); applySearch(); } } $('#left-panel').animate({ 'left': -$('#left-panel').width() + 'px' }); }); var listViewHidden = function () { return ($("#left-panel").css("left") != "0px"); } $("#sltSearchMode").change(function (e) { if ($("#sltSearchMode").val() == 'bufferedArea') { $("#divBuffer").show(); $("#divService").hide(); } else { $("#divBuffer").hide(); $("#divService").show(); } }); $("#btnSettingCancel").click(function () { hideSettingDlg(); }); $("#btnSettingSave").click(function () { applySearch(); }); var applySearch = function () { var category = $("#sltCategory").val(); var subCategory = $('#sltCategorySubtype').val().replace(">=", ">~"); var searchMode = $("#sltSearchMode").val(); var searchLatlng = ol.proj.transform(searchPoint, 'EPSG:3857', 'EPSG:4326'); var args = { "category": category, "subCategory": subCategory, "searchMode": searchMode, "searchPoint": searchLatlng[0] + "," + searchLatlng[1] }; if (searchMode == "serviceArea") { args["driveTime"] = $("#tbxServiceArea").val(); } else { args["distanceBuffer"] = $("#tbxDistance").val(); args["distanceUnit"] = $("#sltDistanceUnit").val(); } $.post(getRootPath() + "SiteSelection/Search", { //: JSON.stringify(args) }, function (res) { resultSource.setUrl(getRootPath() + "/SiteSelection/resultlayer/{z}/{x}/{y}"); $("#result-table tr:gt(0)").remove(); var data = JSON.parse(res); if (data.status == 2) { $("#message").html("Please note that this sample map is only able to analyze service areas within the Frisco, TX city limits, <br\>which are indicated by a dashed red line. Click inside that boundary for best results. "); $("#message").show().delay(5000).fadeOut(); } if (data.status == 1) { $("#message").text("No results found."); $("#message").show().delay(5000).fadeOut(); } if (data.status == 0) { bindSearchResult(data.features); } }); hideSettingDlg(); } }); /* functions for result panel*/ function bindSearchResult(queryItems) { // remove all the lines except the header $("#result-table tr:gt(0)").remove(); // Display data in the Grid table for (var i = 0; i < queryItems.length; i++) { var name = queryItems[i].name; var position = queryItems[i].point; var newRow = $("<tr>"); newRow.append('<td><a style="width:14px;height:14px;display:block;"><img alt="Search" title="Zoom to sepcified POI" src="Images/find.png" onclick="zoomToPoi(' + position.split(',')[0] + ',' + position.split(',')[1] + ')" /></a></td>'); newRow.append("<td>" + name + "</td>"); $("#result-table > tbody:last").append(newRow); } } function zoomToPoi(lat, lng) { var projectedCenter = ol.proj.transform([lng,|lat], 'EPSG:4326', 'EPSG:3857'); map.setView(new ol.View({ center: projectedCenter, zoom: 16 })); } /* setting dialog events*/ function showSettingDlg() { this.bgmask = document.createElement('div'); this.bgmask.id = 'bg-mask'; $('body').append(this.bgmask); $('#edit-panel').slideToggle("fast"); } function hideSettingDlg() { if ($('#edit-panel').is(':visible')) { $('.bg-mask').remove(); $('#edit-panel').slideToggle("fast"); } } function showResultDlg() { $('#left-panel').animate({ 'left': '0px' }); } </script> </body> </html>
/** * Define a namespace for the application. */ window.app = {}; var app = window.app; /** * @constructor * @extends {ol.control.Control} * @param {Object=} opt_options Control options. */ app.ImagesControl = function (opt_options) { var options = opt_options || {}; var element = document.createElement('div'); element.className = 'img-control ol-unselectable'; for (var i = 0; i < options.imgs.length; i++) { var img = document.createElement('img'); img.id = options.imgs[i].id; img.src = options.imgs[i].src; if (options.imgs[i].css) { img.className = options.imgs[i].css; } img.title = options.imgs[i].title; img.callback = options.imgs[i].callback; img.context = this; var handleCallback = function (e) { // prevent #rotate-north anchor from getting appended to the url e.preventDefault(); if (this.callback) { this.callback(e); } }; img.addEventListener('click', handleCallback, false); img.addEventListener('touchstart', handleCallback, false); element.appendChild(img); } ol.control.Control.call(this, { element: element, target: options.target }); }; ol.inherits(app.ImagesControl, ol.control.Control); // add get root path method. getRootPath = function () { var pathArray = location.pathname.split('/'); var appPath = "/"; for (var i = 1; i < pathArray.length - 1; i++) { appPath += pathArray[i] + "/"; } return appPath === "/" ? "" : appPath; };