tag:blogger.com,1999:blog-48897246753314623172024-03-25T20:58:22.703+07:00pixelcookerGIS and Remote Sensing Tutorial for Allgeo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.comBlogger337125tag:blogger.com,1999:blog-4889724675331462317.post-30788042732715986382024-01-07T13:14:00.002+07:002024-01-07T13:14:32.197+07:00Polygon Simplification in GIS. Avoid Gaps and Slivers, Reduced File Size, Consistent Appearance, Attributes Preservation<div><div>in this video I would like to share how to simplify polygons data for non-topological format such as ESRI Shapefile, KML or JSON/GEOJSON. Perform polygon data manipulation such as simplify in non-topological gis data format if not done correctly will lead to causing slivers and gaps in the polygon border. Simplifying methods being used is also has a role in this problem. </div><div>The safest approach to do polygons simplify usually by converting the data to polylines first, then after simplifying, the data converted back to polygon. This approach will be tedious for large dataset, and prone to attributes table records matching loss. </div><div>This video is about how to avoids those kinds of problems. </div></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/fnyTF8JQqPo?si=R4Qt1JD2FkqKTXwh" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-31692160520717757272023-12-26T13:59:00.004+07:002023-12-26T13:59:49.722+07:00ArcGIS Pro Trick. A fast way to store your Statistical Classification Permanently<div><div>In the old times of ArcMap or any other GIS Software, storing the statistical classification from the symbology setting usually takes efforts of repeated query and field calculations. For example, classifying population attributes using Natural Breaks/Jenks classification method can only be done on-the-fly. </div><div>The classified values are not saved in the attribute table, so, if we want to use the classified values, we must repeat the classification. In certain cases, this will cause some difficulties when we need to share the analysis to other party. Fortunately, ArcGIS Pro has this built-in geoprocessing tool </div><div>to handle this kind of task in very fast and easy way. The tool is called Reclassify Field, and here is how to use it. </div></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/YzOLxsnCv_k?si=oUXba-riZLEhIknS" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-23480204579949375902023-12-20T09:27:00.005+07:002023-12-20T09:29:04.378+07:00Generates Hexagonal Cartogram in ArcGIS<div><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-size: 16px; margin: 1.25em 0px; white-space-collapse: preserve;"><span style="color: #f3f3f3; font-family: inherit;">This article delves into the realm of cartogram generation within ArcGIS, a leading Geographic Information System (GIS) platform. We explore the intricacies of cartogram creation using ArcGIS, focusing on the underlying techniques, real-world applications, and best practices for effective visualization. From understanding the tools available in ArcGIS to addressing specific challenges unique to this environment, this comprehensive guide serves as a practical resource for GIS professionals and enthusiasts.</span></p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-size: 16px; margin: 1.25em 0px; white-space-collapse: preserve;"><span color="var(--tw-prose-bold)" style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #f3f3f3; font-family: inherit; font-weight: 600;">Introduction:</span></p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-size: 16px; margin: 1.25em 0px; white-space-collapse: preserve;"><span style="color: #f3f3f3; font-family: inherit;">ArcGIS, developed by Esri, is a widely used GIS software that provides robust tools for spatial analysis and visualization. Within the expansive suite of capabilities that ArcGIS offers, cartogram generation stands out as a powerful method for distorting geographic features based on variable data. This article navigates through the specific functionalities, workflows, and considerations involved in creating cartograms within the ArcGIS environment.</span></p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-size: 16px; margin: 1.25em 0px; white-space-collapse: preserve;"><span color="var(--tw-prose-bold)" style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #f3f3f3; font-family: inherit; font-weight: 600;">Understanding Cartogram Generation in ArcGIS:</span></p><ol style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-reset: list-number 0; display: flex; flex-direction: column; font-size: 16px; list-style: none; margin: 1.25em 0px; padding: 0px; white-space-collapse: preserve;"><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><span style="color: #f3f3f3; font-family: inherit;"><span color="var(--tw-prose-bold)" style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-weight: 600;">ArcGIS Cartogram Tools:</span>
ArcGIS provides dedicated tools for cartogram generation, allowing users to transform conventional maps into dynamic representations of data. The Cartogram toolset includes features such as the Aggregate Polygons tool, enabling the distortion of polygons based on a chosen attribute.</span></p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><span style="color: #f3f3f3; font-family: inherit;"><span color="var(--tw-prose-bold)" style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-weight: 600;">Data Preparation:</span>
Successful cartogram generation begins with the preparation of the underlying spatial and attribute data. This section explores the steps involved in organizing data within ArcGIS, ensuring that it is formatted appropriately for cartogram creation.</span></p></li></ol><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-size: 16px; margin: 1.25em 0px; white-space-collapse: preserve;"><span color="var(--tw-prose-bold)" style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #f3f3f3; font-family: inherit; font-weight: 600;">Applications of ArcGIS Cartograms:</span></p><ol style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-reset: list-number 0; display: flex; flex-direction: column; font-size: 16px; list-style: none; margin: 1.25em 0px; padding: 0px; white-space-collapse: preserve;"><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><span style="color: #f3f3f3; font-family: inherit;"><span color="var(--tw-prose-bold)" style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-weight: 600;">Demographic Insights:</span>
Showcase how cartograms in ArcGIS are instrumental in visualizing demographic patterns, population density, and migration trends. Using real-world examples, highlight how these maps can reveal valuable insights for urban planning and resource allocation.</span></p></li><li style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; counter-increment: list-number 1; display: block; margin-bottom: 0px; margin-top: 0px; min-height: 28px; padding-left: 0.375em;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; margin: 0px;"><span style="color: #f3f3f3; font-family: inherit;"><span color="var(--tw-prose-bold)" style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-weight: 600;">Election Mapping:</span>
Explore the use of ArcGIS cartograms for election mapping, showcasing how they effectively communicate voting patterns, political landscapes, and electoral outcomes at various spatial scales.</span></p></li></ol></div><div><span face="Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"" style="color: #f3f3f3; font-family: inherit; font-size: 16px; font-weight: 600; white-space-collapse: preserve;">Creating Cartograms in ArcGIS:</span></div><div><span style="color: #f3f3f3;"><span face="Söhne, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji"><span style="white-space-collapse: preserve;"><b> </b></span></span><span face="Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"" style="font-size: 16px; white-space-collapse: preserve;">Video tutorial below demonstrate how to generate simple cartogram from polygon data in ArcGIS Desktop. The workflow described in the video also can be performed in ArcGIS Pro, QGIS or other GIS software as long as they have spatial join tool, tessellation grid generation tool, and selection by location tool. </span></span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/0K9alAizKKE?si=waa7BQKy-f6rS9hN" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-2092367235317089722023-12-10T21:57:00.003+07:002023-12-10T21:57:49.947+07:00Creating a Web Mapping Application with Leaflet JS<p><span style="font-family: inherit;"><span face="Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"" style="background-color: #343541; color: #d1d5db; font-size: 16px; white-space-collapse: preserve;">Web mapping applications are powerful tools that enable users to visualize and interact with geographical data. In this tutorial, we'll explore how to build a simple yet effective mapping application using Leaflet JS, a popular JavaScript library for interactive maps.</span> </span></p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; background-color: #343541; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; color: #d1d5db; font-size: 16px; margin: 0px 0px 1.25em; white-space-collapse: preserve;"><span style="font-family: inherit;">Leaflet JS is a lightweight, open-source library for creating mobile-friendly interactive maps. It provides a simple and intuitive API for incorporating maps into web pages. </span></p><div><span style="background-color: #343541; color: #d1d5db; font-family: inherit; white-space-collapse: preserve;">A client in FIVVER (if you needs my service for your GIS Job, the FIVVER link on the left top bar of my blog) asked me to make a simple webmapping application using Leaflet JS that has functionality to zoom and pan in seamless way based on the attribute table selection.</span></div><div><span style="background-color: #343541; color: #d1d5db; font-family: inherit; white-space-collapse: preserve;"><br /></span></div><div><span style="background-color: #343541; color: #d1d5db; font-family: inherit; white-space-collapse: preserve;">The data is stored as GEOJSON file and directly injected in the HTML, so the HTML webmap can be opened and distributed in various computer at ease. </span></div><div><span style="background-color: #343541; color: #d1d5db; font-family: inherit; white-space-collapse: preserve;"><br /></span></div><div><span face="Söhne, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji" style="color: #d1d5db;"><span style="background-color: #343541; font-family: inherit; white-space-collapse: preserve;">I design this webmap with simplicity mindset, so reproduction into another website can be done easily. </span></span></div><div><span face="Söhne, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji" style="color: #d1d5db;"><span style="background-color: #343541; font-family: inherit; white-space-collapse: preserve;"><br /></span></span></div><div><span face="Söhne, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji" style="color: #d1d5db;"><span style="background-color: #343541; font-family: inherit; white-space-collapse: preserve;">If you are curious about the code and probably consider to use it for your own purposes, here is the code </span></span></div><div><span face="Söhne, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji" style="color: #d1d5db;"><span style="background-color: #343541; white-space-collapse: preserve;"><br /></span></span></div><div><span face="Söhne, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji" style="color: #d1d5db;"><span style="background-color: #343541; white-space-collapse: preserve;"><br /></span></span></div><!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #557799;"><!DOCTYPE html></span>
<span style="color: #007700;"><html</span> <span style="color: #0000cc;">lang=</span><span style="background-color: #fff0f0;">"en"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><head></span>
<span style="color: #007700;"><meta</span> <span style="color: #0000cc;">charset=</span><span style="background-color: #fff0f0;">"UTF-8"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><meta</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"viewport"</span> <span style="color: #0000cc;">content=</span><span style="background-color: #fff0f0;">"width=device-width, initial-scale=1.0"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><title></span>CY2024 Health Equity Learning Collaborative Participants Viewer <span style="color: #007700;"></title></span>
<span style="color: #888888;"><!-- Include Leaflet CSS and JS --></span>
<span style="color: #007700;"><link</span> <span style="color: #0000cc;">rel=</span><span style="background-color: #fff0f0;">"stylesheet"</span> <span style="color: #0000cc;">href=</span><span style="background-color: #fff0f0;">"https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><script </span><span style="color: #0000cc;">src=</span><span style="background-color: #fff0f0;">"https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"</span><span style="color: #007700;">></script></span>
<span style="color: #007700;"><style></span>
<span style="color: #888888;">/* Set the map container to fill the entire screen */</span>
<span style="color: #0066bb; font-weight: bold;">#map</span> {
<span style="color: #008800; font-weight: bold;">height</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span>vh;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> {
<span style="color: #008800; font-weight: bold;">max-height</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">400px</span>;
<span style="color: #008800; font-weight: bold;">overflow-y</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">auto</span>;
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">10px</span>;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">400px</span>; <span style="color: #888888;">/* Set the width of the table container */</span>
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">table</span> {
<span style="color: #008800; font-weight: bold;">border-collapse</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">collapse</span>;
<span style="color: #008800; font-weight: bold;">border-spacing</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span>;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">th</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">td</span> {
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1px</span> <span style="color: #008800; font-weight: bold;">solid</span> <span style="color: #6600ee; font-weight: bold;">#ddd</span>;
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">12px</span>;
<span style="color: #008800; font-weight: bold;">text-align</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">left</span>;
<span style="color: #008800; font-weight: bold;">cursor</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">pointer</span>;
word<span style="color: #333333;">-</span>wrap<span style="color: #333333;">:</span> break<span style="color: #333333;">-</span>word; <span style="color: #888888;">/* Allow content to wrap within cells */</span>
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">th</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#87CEEB</span>; <span style="color: #888888;">/* Light Blue */</span>
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#fff</span>; <span style="color: #888888;">/* White text color */</span>
<span style="color: #008800; font-weight: bold;">position</span><span style="color: #333333;">:</span> sticky;
<span style="color: #008800; font-weight: bold;">top</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">-10px</span>;
<span style="color: #008800; font-weight: bold;">z-index</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">2</span>; <span style="color: #888888;">/* Increase the z-index to keep the header above the tbody */</span>
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">tr</span><span style="color: #555555; font-weight: bold;">:hover</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#f5f5f5</span>;
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">thead</span><span style="color: #333333;">,</span>
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">tbody</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> table;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> calc(<span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span> <span style="color: #333333;">-</span> <span style="color: #6600ee; font-weight: bold;">17px</span>); <span style="color: #888888;">/* Adjust for scrollbar width */</span>
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">thead</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">table-header-group</span>;
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">tbody</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">table-row</span><span style="color: #333333;">-</span>group;
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">tbody</span> <span style="color: #007700;">tr</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#fff</span>;
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">tbody</span> <span style="color: #007700;">tr</span><span style="color: #bb0066; font-weight: bold;">.green</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">green</span>;
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#fff</span>; <span style="color: #888888;">/* White text color for green background */</span>
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">tbody</span> <span style="color: #007700;">tr</span><span style="color: #bb0066; font-weight: bold;">.yellow</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">yellow</span>;
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">#000</span>; <span style="color: #888888;">/* Black text color for yellow background */</span>
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">th</span><span style="color: #555555; font-weight: bold;">:nth-child</span><span style="color: #333333;">(</span><span style="color: #007700;">1</span><span style="color: #333333;">),</span>
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">td</span><span style="color: #555555; font-weight: bold;">:nth-child</span><span style="color: #333333;">(</span><span style="color: #007700;">1</span><span style="color: #333333;">)</span> {
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">50</span><span style="color: #333333;">%</span>; <span style="color: #888888;">/* Adjust the width as needed */</span>
}
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">th</span><span style="color: #555555; font-weight: bold;">:nth-child</span><span style="color: #333333;">(</span><span style="color: #007700;">2</span><span style="color: #333333;">),</span>
<span style="color: #bb0066; font-weight: bold;">.attribute-table</span> <span style="color: #007700;">td</span><span style="color: #555555; font-weight: bold;">:nth-child</span><span style="color: #333333;">(</span><span style="color: #007700;">2</span><span style="color: #333333;">)</span> {
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">50</span><span style="color: #333333;">%</span>; <span style="color: #888888;">/* Adjust the width as needed */</span>
}
<span style="color: #bb0066; font-weight: bold;">.no-scroll-map</span> {
<span style="color: #008800; font-weight: bold;">pointer</span><span style="color: #333333;">-</span>events<span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
}
<span style="color: #bb0066; font-weight: bold;">.legend</span> {
<span style="color: #008800; font-weight: bold;">position</span><span style="color: #333333;">:</span> bottomleft;
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">white</span>;
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">10px</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1px</span> <span style="color: #008800; font-weight: bold;">solid</span> <span style="color: #6600ee; font-weight: bold;">#ccc</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">-</span>radius<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">5px</span>;
box<span style="color: #333333;">-</span>shadow<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span> <span style="color: #6600ee; font-weight: bold;">0</span> <span style="color: #6600ee; font-weight: bold;">15px</span> rgba(<span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">,</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">,</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">,</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">.</span><span style="color: #6600ee; font-weight: bold;">2</span>);
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">14px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.legend</span> <span style="color: #007700;">h4</span> {
<span style="color: #008800; font-weight: bold;">margin-top</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span>;
<span style="color: #008800; font-weight: bold;">margin-bottom</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">10px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.legend-item</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> flex;
align<span style="color: #333333;">-</span>items<span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">center</span>;
<span style="color: #008800; font-weight: bold;">margin-bottom</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">8px</span>;
}
<span style="color: #bb0066; font-weight: bold;">.legend-color</span> {
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">20px</span>;
<span style="color: #008800; font-weight: bold;">height</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">20px</span>;
<span style="color: #008800; font-weight: bold;">margin-right</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">8px</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1px</span> <span style="color: #008800; font-weight: bold;">solid</span> <span style="color: #6600ee; font-weight: bold;">#ccc</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">-</span>radius<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">5px</span>;
}
<span style="color: #007700;"></style></span>
<span style="color: #007700;"></head></span>
<span style="color: #007700;"><body></span>
<span style="color: #888888;"><!-- Create a container for the map --></span>
<span style="color: #007700;"><div</span> <span style="color: #0000cc;">id=</span><span style="background-color: #fff0f0;">"map"</span><span style="color: #007700;">></div></span>
<span style="color: #007700;"><script></span>
<span style="color: #008800; font-weight: bold;">var</span> map <span style="color: #333333;">=</span> L.map(<span style="background-color: #fff0f0;">'map'</span>, {
center<span style="color: #333333;">:</span> [<span style="color: #6600ee; font-weight: bold;">39.748824</span>, <span style="color: #333333;">-</span><span style="color: #6600ee; font-weight: bold;">84.209605</span>],
zoom<span style="color: #333333;">:</span> <span style="color: #0000dd; font-weight: bold;">4</span>,
});
<span style="color: #888888;">// Enable scroll wheel zoom when the map is loaded</span>
map.on(<span style="background-color: #fff0f0;">'load'</span>, <span style="color: #008800; font-weight: bold;">function</span> () {
map.scrollWheelZoom.enable();
});
<span style="color: #888888;">// Add a base map layer (you can choose a different one if you like)</span>
L.tileLayer(<span style="background-color: #fff0f0;">'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'</span>, {
attribution<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'© OpenStreetMap contributors'</span>
}).addTo(map);
<span style="color: #888888;">// Parse the GeoJSON data</span>
<span style="color: #008800; font-weight: bold;">var</span> geojson_data <span style="color: #333333;">=</span> {
<span style="color: #888888;">// Define a GeoJSON layer and add it to the map</span>
<span style="color: #008800; font-weight: bold;">var</span> geojsonLayer <span style="color: #333333;">=</span> L.geoJSON(geojson_data, {
pointToLayer<span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">function</span> (feature, latlng) {
<span style="color: #008800; font-weight: bold;">return</span> L.circleMarker(latlng, {
radius<span style="color: #333333;">:</span> <span style="color: #0000dd; font-weight: bold;">8</span>,
fillColor<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'green'</span>,
color<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'#000'</span>,
weight<span style="color: #333333;">:</span> <span style="color: #0000dd; font-weight: bold;">1</span>,
opacity<span style="color: #333333;">:</span> <span style="color: #0000dd; font-weight: bold;">1</span>,
fillOpacity<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0.8</span>
});
},
onEachFeature<span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">function</span> (feature, layer) {
<span style="color: #888888;">// Popup with information from GeoJSON properties</span>
<span style="color: #008800; font-weight: bold;">var</span> popupContent <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"<p><b>Organization:</b> "</span> <span style="color: #333333;">+</span> feature.properties.Organizati <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">"</p>"</span> <span style="color: #333333;">+</span>
<span style="background-color: #fff0f0;">"<p><b>Address:</b> "</span> <span style="color: #333333;">+</span> feature.properties.Address_1 <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">"</p>"</span>;
layer.bindPopup(popupContent);
<span style="color: #888888;">// Hover popup showing only Org_name and Address_1</span>
layer.on(<span style="background-color: #fff0f0;">'mouseover'</span>, <span style="color: #008800; font-weight: bold;">function</span> (e) {
<span style="color: #008800; font-weight: bold;">this</span>.openPopup();
});
layer.on(<span style="background-color: #fff0f0;">'mouseout'</span>, <span style="color: #008800; font-weight: bold;">function</span> (e) {
<span style="color: #008800; font-weight: bold;">this</span>.closePopup();
});
}
});
geojsonLayer.addTo(map);
<span style="color: #888888;">// Function to process a GeoJSON layer and add rows to the attribute table</span>
<span style="color: #008800; font-weight: bold;">function</span> processGeojsonLayer(layer, tbody, layerClass) {
layer.eachLayer(<span style="color: #008800; font-weight: bold;">function</span> (layer) {
<span style="color: #008800; font-weight: bold;">var</span> row <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'tr'</span>, layerClass, tbody);
<span style="color: #888888;">// Add Organization cell</span>
<span style="color: #008800; font-weight: bold;">var</span> orgCell <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'td'</span>, <span style="background-color: #fff0f0;">''</span>, row);
orgCell.innerHTML <span style="color: #333333;">=</span> layer.feature.properties.Organizati;
orgCell.addEventListener(<span style="background-color: #fff0f0;">'click'</span>, <span style="color: #008800; font-weight: bold;">function</span> () {
map.flyTo(layer.getLatLng(), <span style="color: #0000dd; font-weight: bold;">15</span>, {
duration<span style="color: #333333;">:</span> <span style="color: #0000dd; font-weight: bold;">2</span>,
easeLinearity<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0.25</span>,
});
});
<span style="color: #888888;">// Add Address cell</span>
<span style="color: #008800; font-weight: bold;">var</span> addressCell <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'td'</span>, <span style="background-color: #fff0f0;">''</span>, row);
addressCell.innerHTML <span style="color: #333333;">=</span> layer.feature.properties.Address_1;
addressCell.addEventListener(<span style="background-color: #fff0f0;">'click'</span>, <span style="color: #008800; font-weight: bold;">function</span> () {
map.flyTo(layer.getLatLng(), <span style="color: #0000dd; font-weight: bold;">15</span>, {
duration<span style="color: #333333;">:</span> <span style="color: #0000dd; font-weight: bold;">2</span>,
easeLinearity<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0.25</span>,
});
});
<span style="color: #888888;">// Set the row background color to match the circle color</span>
row.style.backgroundColor <span style="color: #333333;">=</span> layer.options.fillColor;
});
}
<span style="color: #888888;">// Create a custom control for the attribute table</span>
<span style="color: #008800; font-weight: bold;">var</span> attributeControl <span style="color: #333333;">=</span> L.control({ position<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'bottomright'</span> });
attributeControl.onAdd <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">function</span> (map) {
<span style="color: #008800; font-weight: bold;">var</span> div <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'div'</span>, <span style="background-color: #fff0f0;">'info attribute-table'</span>);
<span style="color: #008800; font-weight: bold;">var</span> table <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'table'</span>, <span style="background-color: #fff0f0;">''</span>, div);
<span style="color: #008800; font-weight: bold;">var</span> thead <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'thead'</span>, <span style="background-color: #fff0f0;">''</span>, table);
<span style="color: #008800; font-weight: bold;">var</span> tbody <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'tbody'</span>, <span style="background-color: #fff0f0;">''</span>, table);
<span style="color: #008800; font-weight: bold;">var</span> headerRow <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'tr'</span>, <span style="background-color: #fff0f0;">''</span>, thead);
L.DomUtil.create(<span style="background-color: #fff0f0;">'th'</span>, <span style="background-color: #fff0f0;">''</span>, headerRow).innerHTML <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">'Organization'</span>;
L.DomUtil.create(<span style="background-color: #fff0f0;">'th'</span>, <span style="background-color: #fff0f0;">''</span>, headerRow).innerHTML <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">'Address'</span>;
<span style="color: #888888;">// Process geojsonLayer initially</span>
processGeojsonLayer(geojsonLayer, tbody, <span style="background-color: #fff0f0;">'green'</span>);
<span style="color: #008800; font-weight: bold;">return</span> div;
};
attributeControl.addTo(map);
<span style="color: #888888;">// Create a layer control with base map and GeoJSON layer</span>
<span style="color: #008800; font-weight: bold;">var</span> baseMaps <span style="color: #333333;">=</span> {
<span style="background-color: #fff0f0;">"OpenStreetMap"</span><span style="color: #333333;">:</span> L.tileLayer(<span style="background-color: #fff0f0;">'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'</span>, {
attribution<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'© OpenStreetMap contributors'</span>
})
};
<span style="color: #008800; font-weight: bold;">var</span> overlayMaps <span style="color: #333333;">=</span> {
<span style="background-color: #fff0f0;">"CY2024 HELC Participants"</span><span style="color: #333333;">:</span> geojsonLayer,
};
L.control.layers(baseMaps, overlayMaps, { collapsed<span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">false</span> }).addTo(map);
<span style="color: #888888;">// Add event listeners to enable/disable scroll wheel zoom based on cursor position</span>
<span style="color: #008800; font-weight: bold;">var</span> attributeTable <span style="color: #333333;">=</span> <span style="color: #007020;">document</span>.querySelector(<span style="background-color: #fff0f0;">'.attribute-table'</span>);
attributeTable.addEventListener(<span style="background-color: #fff0f0;">'mouseenter'</span>, <span style="color: #008800; font-weight: bold;">function</span> () {
map.scrollWheelZoom.disable();
});
attributeTable.addEventListener(<span style="background-color: #fff0f0;">'mouseleave'</span>, <span style="color: #008800; font-weight: bold;">function</span> () {
map.scrollWheelZoom.enable();
});
<span style="color: #888888;">// Listen for overlay add/remove events to update the attribute table</span>
map.on(<span style="background-color: #fff0f0;">'overlayadd'</span>, <span style="color: #008800; font-weight: bold;">function</span> (event) {
<span style="color: #008800; font-weight: bold;">if</span> (event.layer <span style="color: #333333;">===</span> geojsonLayer <span style="color: #333333;">||</span> event.layer <span style="color: #333333;">===</span> geojsonLayer2) {
updateAttributeTable();
}
});
map.on(<span style="background-color: #fff0f0;">'overlayremove'</span>, <span style="color: #008800; font-weight: bold;">function</span> (event) {
<span style="color: #008800; font-weight: bold;">if</span> (event.layer <span style="color: #333333;">===</span> geojsonLayer <span style="color: #333333;">||</span> event.layer <span style="color: #333333;">===</span> geojsonLayer2) {
updateAttributeTable();
}
});
<span style="color: #888888;">// Function to update the attribute table based on the currently visible layers</span>
<span style="color: #008800; font-weight: bold;">function</span> updateAttributeTable() {
<span style="color: #888888;">// Clear the existing table rows</span>
<span style="color: #008800; font-weight: bold;">var</span> tbody <span style="color: #333333;">=</span> <span style="color: #007020;">document</span>.querySelector(<span style="background-color: #fff0f0;">'.attribute-table tbody'</span>);
tbody.innerHTML <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">''</span>;
<span style="color: #888888;">// Process geojsonLayer if it is visible</span>
<span style="color: #008800; font-weight: bold;">if</span> (map.hasLayer(geojsonLayer)) {
processGeojsonLayer(geojsonLayer, tbody, <span style="background-color: #fff0f0;">'green'</span>);
}
<span style="color: #888888;">// Process geojsonLayer2 if it is visible</span>
<span style="color: #008800; font-weight: bold;">if</span> (map.hasLayer(geojsonLayer2)) {
processGeojsonLayer(geojsonLayer2, tbody, <span style="background-color: #fff0f0;">'yellow'</span>);
}
}
<span style="color: #888888;">// Create a legend control</span>
<span style="color: #008800; font-weight: bold;">var</span> legendControl <span style="color: #333333;">=</span> L.control({ position<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'bottomleft'</span> });
legendControl.onAdd <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">function</span> (map) {
<span style="color: #008800; font-weight: bold;">var</span> legendDiv <span style="color: #333333;">=</span> L.DomUtil.create(<span style="background-color: #fff0f0;">'div'</span>, <span style="background-color: #fff0f0;">'legend'</span>);
<span style="color: #008800; font-weight: bold;">var</span> legendContent <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">'<h4>Legend</h4>'</span>;
<span style="color: #888888;">// Legend items</span>
<span style="color: #008800; font-weight: bold;">var</span> legendItems <span style="color: #333333;">=</span> [
{ color<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'green'</span>, label<span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">'CY2024 Health Equity Learning Collaborative Participants'</span> },
];
legendItems.forEach(<span style="color: #008800; font-weight: bold;">function</span> (item) {
legendContent <span style="color: #333333;">+=</span> <span style="background-color: #fff0f0;">'<div class="legend-item">'</span>;
legendContent <span style="color: #333333;">+=</span> <span style="background-color: #fff0f0;">'<div class="legend-color" style="background-color: '</span> <span style="color: #333333;">+</span> item.color <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">'"></div>'</span>;
legendContent <span style="color: #333333;">+=</span> <span style="background-color: #fff0f0;">'<div>'</span> <span style="color: #333333;">+</span> item.label <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">'</div>'</span>;
legendContent <span style="color: #333333;">+=</span> <span style="background-color: #fff0f0;">'</div>'</span>;
});
legendDiv.innerHTML <span style="color: #333333;">=</span> legendContent;
<span style="color: #008800; font-weight: bold;">return</span> legendDiv;
};
legendControl.addTo(map);
<span style="color: #007700;"></script></span>
<span style="color: #007700;"></body></span>
<span style="color: #007700;"></html></span></pre></div><div><br /></div><div><span style="color: #d1d5db;"><span style="background-color: #343541; white-space-collapse: preserve;">Just feed your GEOJSON data in the geojson_layer variable, set the popup attribute according to your preferred fields list, and you are good to go. Here is a preview of the finished app. </span></span></div><div><span style="color: #d1d5db;"><span style="background-color: #343541; white-space-collapse: preserve;"><br /></span></span></div><div><span style="color: #d1d5db;"><span style="background-color: #343541; white-space-collapse: preserve;">LIVE DEMO can be accessed from this <a href="https://geo2004.github.io/leaflet/HELC.html" target="_blank">LINK</a>. </span></span></div><div><span style="color: #d1d5db;"><span style="background-color: #343541; white-space-collapse: preserve;"><br /></span></span></div><div><span style="color: #d1d5db;"><span style="background-color: #343541; white-space-collapse: preserve;"><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh5pFBr7TUw_K9ooW6LKJWyrzKoW24OHtVAX7UcTPzndou-AbsewkuwRk1lqT3bN6G1dk0-y4BmEqgDAqRLAGBE7aVkkvk-Y5j-DfmUlJqRM_ZAG_bzywc96ZEnTdvsJ3wpdGAQP9082nN8CQapuYRuCy5tZEP8tx67rMly9aJ-p1QVXDPmJShJfZQBjeg" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="978" data-original-width="1910" height="328" src="https://blogger.googleusercontent.com/img/a/AVvXsEh5pFBr7TUw_K9ooW6LKJWyrzKoW24OHtVAX7UcTPzndou-AbsewkuwRk1lqT3bN6G1dk0-y4BmEqgDAqRLAGBE7aVkkvk-Y5j-DfmUlJqRM_ZAG_bzywc96ZEnTdvsJ3wpdGAQP9082nN8CQapuYRuCy5tZEP8tx67rMly9aJ-p1QVXDPmJShJfZQBjeg=w640-h328" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;">If you find an error in using the CODE, mail me at mappingsince2004@gmail.com </div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: left;"><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; margin: 1.25em 0px;">Feel free to customize and expand upon this foundation to meet your specific needs. Leaflet JS offers a rich set of features for creating dynamic and interactive maps, making it a powerful tool for a wide range of mapping applications.</p><p style="--tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-ring-color: rgba(69,89,164,.5); --tw-ring-offset-color: #fff; --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-offset-width: 0px; --tw-ring-shadow: 0 0 transparent; --tw-rotate: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-shadow-colored: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-skew-x: 0; --tw-skew-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; border: 0px solid rgb(217, 217, 227); box-sizing: border-box; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; margin: 1.25em 0px 0px;">Happy mapping!</p></div><br /><br /></div><br /><br /></span></span></div>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-51702695973281191902023-11-14T09:49:00.004+07:002023-11-14T09:49:37.121+07:00Turn Your QGIS Projects into Interactive Web Maps in Minutes!<div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;">Embark on an exciting journey as we reveal the wizardry behind transforming your QGIS projects into captivating web maps. In just a few clicks, you can breathe life into your static visualizations, creating an interactive online experience that's both powerful and effortless. Don't miss out on this game-changing tutorial – the link to the video awaits you at the end of this blog post!</span></span></div><div><span style="background-color: #444444;"><br /></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;">Discover the incredible capabilities of the OpenGIS Plugin as it effortlessly bridges the gap between your QGIS desktop and the online realm. From intricate heatmaps to sophisticated choropleths, every nuance of your original visualizations is preserved. This is your chance to elevate your maps to new heights, making them not just informative but engaging. Click the video link to witness the transformation firsthand.</span></span></div><div><span style="background-color: #666666; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;"><br /></span></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;">Flexibility meets convenience with the OpenGIS Plugin. Once your web map masterpiece is ready, the choice of deployment is yours. Whether it's the familiar GitHub or other hosting alternatives tailored to your preferences, the OpenGIS Plugin ensures that your maps are accessible to a global audience. The excitement doesn't end here – delve into the video to unlock the secrets of hassle-free deployment.</span></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;"><br /></span></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;">Navigate your maps seamlessly with the OpenGIS Plugin, bringing all the essential tools from QGIS to the online stage. Panning, zooming, and interacting with your data are as intuitive as ever. Your audience will love the familiar feel, ensuring they stay engaged and informed. Ready to see it in action? Follow the video link for an exclusive walkthrough of the user-friendly navigation features.</span></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;"><br /></span></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;">And here's the best part – the OpenGIS Plugin offers a free lite version, making this transformative experience accessible to all. Whether you're a seasoned GIS professional or a beginner taking your first steps, this plugin empowers you without the hefty price tag. Click the video link to witness how the OpenGIS Plugin can revolutionize your mapping experience, starting with a risk-free exploration of its capabilities.</span></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;"><br /></span></span></div><div><span style="background-color: #444444; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><span style="color: white;">In conclusion, the OpenGIS Plugin is your ticket to unlocking the full potential of your QGIS projects. The video link at the end of this post is your gateway to a world where maps come alive online. Don't just read about it – watch the tutorial and witness the magic unfold. Your maps deserve to be more than static visuals, and the OpenGIS Plugin is here to make that transformation a reality. Click now and let the adventure begin!</span></span></div><div><span style="background-color: #f7f7f8; color: #374151; font-family: Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; white-space-collapse: preserve;"><br /></span></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/3VvpxBiGyZw?si=4H48tNNHdTYN_ORf" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-988285181909339982023-09-20T16:36:00.000+07:002023-09-20T16:36:35.927+07:00Generates Distance / Origin - Destination Matrix of Two Point Layers in QGIS<div>Here is a short video (under one minute) tutorial about how to perform and calculate Origin - Destination matrix or Distance Matrix between two points layers in QGIS. </div><div><br /></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/JqLAOpsEO2g?si=4hlQQL4lLG3DCFNc" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-66371696794164288482023-07-03T21:02:00.003+07:002023-07-03T21:02:33.895+07:00Satellite Imagery Topographic Correction in QGIS <div><br /></div><div><span style="background-color: rgba(255, 255, 255, 0.1); color: white; font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space-collapse: preserve;">How to generate flat terrain and no topographic undulation in Satellite Imagery. Topographic correction is very helpful for Landcover/landuse classification in steep, hilly or mountainous terrain. Topographic correction guarantee more spectral consistent values for similar landcover in the sun side slopes and shadowed slopes. In the end, more accurate landcover classification can be obtained. </span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/k4EDLmEaIBk" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-50599481155255191692023-06-30T19:46:00.002+07:002023-06-30T19:46:17.937+07:00Soil and Rocks Minerals Mapping from ASTER Imagery using Unsupervised Spectral Angle Mapper Classifier and Spectral Library References<div><span style="background-color: rgba(255, 255, 255, 0.1); color: white; font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space-collapse: preserve;">How to perform minerals identification and classification of rocks and soil using spectral angle mapper classifier and ENVI software. This demo applied using ASTER imagery, however it is can be extended to Landsat or Sentinel Imagery. Works better in open terrain such as arid or desert region with minimum to none of vegetation cover.
Surface reflectance data (atmospherically corrected) is mandatory for the best result. Field inspection also mandatory to assess the classification accuracy because SAM is very sensitive to different parameter settings. </span></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/iBus7BHOQA0" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-51740417011294537612023-06-29T15:05:00.001+07:002023-06-29T15:05:33.370+07:00Remote Sensing in Geology. Generates Mineralogy Sensitive Color Composite Imagery<div><span style="background-color: rgba(255, 255, 255, 0.1); color: #f1f1f1; font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space-collapse: preserve;">Color composites generation workflow which emphasizes to mineral (clay, iron oxide, and ferrous minerals) distribution over wide area. This workflow can be applied to Landsat-8 or Landsat-9 imagery. Similar workflow also can be done for Sentinel-2 MSI imagery. Workflow can be applied to Level-1 data, and the most optimal is applied to the surface reflectance level data.
Key interpretation about color and mineralogy association:
1. Reddish color = ferrous minerals
2. Greenish color = clay minerals
3. Bluish color = iron oxide minerals</span></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/XLmYqKpxsTs" style="background-image: url(https://i.ytimg.com/vi/XLmYqKpxsTs/hqdefault.jpg);" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-7749481868390096752023-06-18T14:17:00.003+07:002023-06-18T14:17:25.595+07:00Offline Basemap Solution for Mobile Mapping in Android or Apple IOS Devices.<div style="text-align: left;"><span><span style="background-color: #444444; font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;">Hi, this post is about four solutions about how to perform offline basemap creation for mobile mapping in Android or Apple IOS devices. For this first part. I will demonstrate about GeoPDF format that is widely supported in most GIS Software. I will demonstrate how to write GeoPDF in ArcGIS Desktop (ArcGIS Pro also has this functionality) and QGIS, followed by how to load the GeoPDF Map in a supported Android/IOS App. Unfortunately, when this video is made, the only app that can read GeoPDF is only Avenza PDF Maps (available in Android and IOS). The rest is no longer updated (TerraGO GeoPDF) or part of paid services (Global Mapper Mobile Pro).</span><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;">
</span><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;"><br /></span></span></span></div><div style="text-align: left;"><span><span style="background-color: #444444; font-family: inherit; white-space-collapse: preserve;">Utilizing GeoPDF for field mapping basemap is very effective and simple. All data in one file. They are structured and tailored according to your setting on the GIS Desktop. They also provide good loading performance as long as the file is not relatively huge. </span></span></div>
<div style="text-align: left;"><span style="background-color: white;"><span style="font-family: inherit; white-space-collapse: preserve;"><br /></span></span></div>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/p3BCAaXAuT4" title="YouTube video player" width="100%"></iframe><div style="text-align: left;"><span style="background-color: white;"><span style="font-family: inherit; white-space-collapse: preserve;"><br /></span></span></div><div style="text-align: left;"><span style="background-color: #444444;"><span><span style="font-family: inherit; white-space-collapse: preserve;"><span style="font-size: 15px;">For the second part. I will demonstrate the ArcGIS Mobile Map Package (MMPK) format, which is, unfortunately, only supported in the ArcGIS software family. I will demonstrate how to write the MMPK in ArcGIS Pro, followed by how to load the MMPK into the ArcGIS Field Maps available on Android and iOS.</span></span></span><span><span style="font-family: inherit; white-space-collapse: preserve;"><span style="font-size: 15px;">
</span></span></span><span><span style="font-family: inherit; white-space-collapse: preserve;"><span style="font-size: 15px;">MMPK can be treated as a complete mobile mapping data package. It supports various types of vector and raster layers in ArcGIS Native format (shapefiles, rasters, geodatabases, network datasets, locators, and even the ability to reference Map and Feature Services in the mobile app). If you store the vector layer in MMPK, you will retain all the attributes (or not, up to you). This implementation is quite different from other types of offline data packaging, such as Vector Tile. MMPK also has an expiration feature. So, when the expiration date is passed, the map is no longer possible to open in any mobile app. MMPK loading in ArcGIS mobile app (such as ArcGIS Field Maps or ArcGIS Navigator) can also be done anonymously. However, this anonymous access is only available if you publish the MMPK using the ArcGIS Publisher Extension for ArcGIS Pro (sold separately from the main ArcGIS Pro License).</span></span></span></span></div><div style="text-align: left;"><span><span style="font-family: inherit; white-space-collapse: preserve;"><span style="background-color: white; font-size: 15px;"><br /></span></span></span></div>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/daPwOwzQRN4" title="YouTube video player" width="100%"></iframe><p style="text-align: left;"><span style="font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="background-color: rgba(255, 255, 255, 0.1); white-space-collapse: preserve;"><br /></span></span></p><div style="text-align: left;"><span style="background-color: #444444;"><span style="font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;">For this third part. I will demonstrate the MBTiles format. MBTiles is one example of an open format, so, many software and libraries can write MBTiles (Global Mapper, MOBAC, QGIS, GDAL, Mappertive, Mapbox Studio, and many more). MBTiles can host both raster and vector tiles, and currently, there are few apps on Android and iOS that can read them (either free or paid apps).</span></span><span style="font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;">
</span></span><span><span face="Roboto, Arial, sans-serif"><span style="font-family: inherit;"><span style="white-space-collapse: preserve;">In this video, I will demonstrate how to generate MBTiles from a raster file (which can be combined with vectors too if you want) using GDAL, and then I will demonstrate how to read the MBTiles in the LOCUS GIS Mapping App available in the Android Google Play Store. MBTiles is a packed image or vector graphics tile and structured by zoom levels just like other </span></span><span style="white-space-collapse: preserve;">tile mapping</span><span style="font-family: inherit;"><span style="white-space-collapse: preserve;"> standards, so, compared with GeoPDF or KML/KMZ, MBTiles is more dynamic in cartographic visualization. You can set layer symbolization or label treatments at every zoom level differently. This is something you can't do with GeoPDF or KML, although GeoPDF or KML are </span></span><span style="white-space-collapse: preserve;">simpler</span><span style="font-family: inherit;"><span style="white-space-collapse: preserve;"> in terms of file creation. Because it follows a tiling scheme, MBTiles file size can be huge, even for small areas. For this matter, file-based maps like GeoPDF or KML/KMZ are more efficient. All in all, there is no perfection in choosing GIS technology for your application. There are always pros and cons. Your </span></span></span></span><span style="font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;">requirements and goals should always be your guide to achieving a successful application.</span></span></span></div><div style="text-align: left;"><span style="background-color: white;"><span style="font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;"><br /></span></span></span></div><div style="text-align: left;"><span style="background-color: white;"><span style="font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;"><br /></span></span></span></div>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/BY49Zhrw9pM" title="YouTube video player" width="100%"></iframe>
<div style="text-align: left;"><span style="background-color: white; font-family: inherit;"><span><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;"><span style="font-size: 15px;"><br /></span></span></span></span></div><div style="text-align: left;"><span style="background-color: white; font-family: inherit;"><span><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;"><span style="font-size: 15px;"><br /></span></span></span></span></div><p style="text-align: left;"><span style="background-color: #444444; font-family: inherit;"><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;">For the fourth part. I will demonstrate the KMZ SuperOverlay format. KMZ SuperOverlay is like normal KML/KMZ, however, it is dedicated to storing raster data (tiled), so the raster data can be opened in native KML/KMZ software such as Google Earth Pro, and still retain the georeference </span><span face="Roboto, Arial, sans-serif" style="white-space-collapse: preserve;">information.</span></span></p><span style="background-color: #444444; font-family: inherit; white-space-collapse: preserve;">Because KML/KMZ is quite popular compared to other file-based tiled geospatial data formats (such as MBTiles), many GIS and mapping software programs can read it, including some of the best-known mobile mapping apps on Android or iOS. KMZ SuperOverlay is also easier to make compared to others (MBTILES, PMTILES, ArcGIS MMPK, Geopackage), you don't have to specify the planned zoom level. Just load and convert, and you will get the result. So, KMZ SuperOverlay is kind of combining the benefits of GeoPDF and MBTiles for offline basemap serving.
In this video, I will demonstrate how to build a KMZ SuperOverlay using GDAL and Global Mapper, followed by how to open the data in the Android Mapping App. One thing I should tell you, currently, because implementation of KMZ Superoverlay are different in every software (although they are all compatible in Google Earth Pro), only KMZ superoverlay generated in Global Mapper that can be read in Mobile Mapping App such as Locus GIS. This situation might be different in future due to constant software development, so, always check and test before doing the data conversion.</span><div><span face="Roboto, Arial, sans-serif" style="background-color: rgba(255, 255, 255, 0.1); font-size: 14px; white-space-collapse: preserve;"><br /></span></div><div><span face="Roboto, Arial, sans-serif" style="background-color: rgba(255, 255, 255, 0.1); font-size: 14px; white-space-collapse: preserve;"><br /></span></div>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/jAjjsyBJ7rQ" title="YouTube video player" width="100%"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-38316740666165842782023-06-11T20:58:00.005+07:002023-06-11T20:58:51.542+07:00Batch and Mass Exporting ArcGIS MXD to PDF using ArcPy<div>Here is the code if someone need this, </div><div><br /></div><div><br /><!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="background-color: #fff0f0;">import arcpy, sys, os, string</span>
mxdList <span style="color: #333333;">=</span> string<span style="color: #333333;">.</span>split(arcpy<span style="color: #333333;">.</span>GetParameterAsText(<span style="color: #0000dd; font-weight: bold;">0</span>), <span style="background-color: #fff0f0;">";"</span>)
outloc <span style="color: #333333;">=</span> arcpy<span style="color: #333333;">.</span>GetParameterAsText(<span style="color: #0000dd; font-weight: bold;">1</span>)
resolution <span style="color: #333333;">=</span> arcpy<span style="color: #333333;">.</span>GetParameterAsText(<span style="color: #0000dd; font-weight: bold;">2</span>)
georef_info_option <span style="color: #333333;">=</span> arcpy<span style="color: #333333;">.</span>GetParameterAsText(<span style="color: #0000dd; font-weight: bold;">3</span>)
layers_attributes_option <span style="color: #333333;">=</span> arcpy<span style="color: #333333;">.</span>GetParameterAsText(<span style="color: #0000dd; font-weight: bold;">4</span>)
<span style="color: #008800; font-weight: bold;">for</span> item <span style="color: black; font-weight: bold;">in</span> mxdList:
item <span style="color: #333333;">=</span> item<span style="color: #333333;">.</span>strip(<span style="background-color: #fff0f0;">'</span><span style="background-color: #fff0f0; color: #666666; font-weight: bold;">\'</span><span style="background-color: #fff0f0;">'</span>)
mxd <span style="color: #333333;">=</span> arcpy<span style="color: #333333;">.</span>mapping<span style="color: #333333;">.</span>MapDocument(item)
base <span style="color: #333333;">=</span> os<span style="color: #333333;">.</span>path<span style="color: #333333;">.</span>basename(item)
base <span style="color: #333333;">=</span> os<span style="color: #333333;">.</span>path<span style="color: #333333;">.</span>splitext(base)[<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">".pdf"</span>
pdf_path <span style="color: #333333;">=</span> os<span style="color: #333333;">.</span>path<span style="color: #333333;">.</span>join(outloc, base)
<span style="color: #888888;"># Switch to layout view</span>
<span style="color: #008800; font-weight: bold;">for</span> df <span style="color: black; font-weight: bold;">in</span> arcpy<span style="color: #333333;">.</span>mapping<span style="color: #333333;">.</span>ListDataFrames(mxd):
<span style="color: #008800; font-weight: bold;">if</span> df<span style="color: #333333;">.</span>name <span style="color: #333333;">==</span> <span style="background-color: #fff0f0;">"Layers"</span>:
mxd<span style="color: #333333;">.</span>activeView <span style="color: #333333;">=</span> df<span style="color: #333333;">.</span>name
mxd<span style="color: #333333;">.</span>title <span style="color: #333333;">=</span> df<span style="color: #333333;">.</span>name
<span style="color: #888888;"># Export to PDF with specified parameters</span>
arcpy<span style="color: #333333;">.</span>mapping<span style="color: #333333;">.</span>ExportToPDF(mxd, pdf_path, resolution<span style="color: #333333;">=</span>resolution, georef_info<span style="color: #333333;">=</span>georef_info_option, layers_attributes<span style="color: #333333;">=</span>layers_attributes_option)
arcpy<span style="color: #333333;">.</span>AddMessage(base <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">" has been exported to PDF"</span>)
</pre></div>
<span face="Roboto, Arial, sans-serif" style="background-color: rgba(255, 255, 255, 0.1); color: #f1f1f1; font-size: 14px; white-space-collapse: preserve;"><span></span></span></div><div><br /></div><div><br /></div><div><br /></div><div>and here is how to implement it in ArcGIS Desktop<br /><br /><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/9wnr65AEsDk" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-62173769955132999442023-05-30T19:19:00.003+07:002023-05-30T19:19:18.066+07:00Geocoding in Google Sheets<div><span style="background-color: rgba(255, 255, 255, 0.1); font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;"><span style="color: white;">How to perform Forward Geocoding (convert Address to Latitude Longitude Coordinates) automatically in Google Sheets Spreadsheet. Example using OSM's Nominatim API service. Other geocoding services such as Google, Bing, MapQuest, Mapbox, or ArcGIS Online also supported as long as you provide the API key and correct query URL in the URL cells. </span></span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/7_s18qDHmGg" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-79993556598656904402023-05-26T23:27:00.005+07:002023-05-26T23:27:49.487+07:00Fast and Automatic Removal of Dangling Nodes, Pseudo Nodes, and Loose Ends in Polyline GIS Data<div><span style="background-color: #666666; font-size: 14px; white-space: pre-wrap;"><span style="color: white; font-family: inherit;">This video is about how to fix, clean, remove dangling nodes, overshoot, undershoot, or loose ends commonly found in Polyline GIS data, in very fast, automatic and easy way using ArcGIS Desktop (also can be done in ArcGIS Pro). These error will limiting further processing such as polygons generation from polylines data or other needs. The secret is using hidden but super powerful CLEAN command in ArcInfo Coverage format from the golden DOS age of GIS in the 80's. </span></span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/Y_D0boyh65w" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-39930037567774682062023-05-12T00:42:00.006+07:002023-05-12T00:44:02.218+07:00Serverless Raster or Imagery Tile Serving using PMTiles<div><div>A few months ago, I created a video tutorial about how to serve raster or imagery tiles using Github </div><div>using TMS/XYZ Tile Serving protocol. The tiles can be consumed by a web gis app either as a base </div><div>map or operational layer. Although the workflow is proven to be working for general cases, the tiles </div><div>displaying and loading speed are quite mediocre compared to API-based serving such as WMS, </div><div>WMTS, or ArcGIS Services. </div><div><br /></div><div>Now, there is one protocol called PMTiles that can also provide similar functionality with additional </div><div>features and better loading/displaying performance. PMTiles in many ways is similar to Mapbox </div><div>MBTiles format (the tiles are packed into a single file), or ArcGIS's TPK Package. However, PMTiles </div><div>can be served directly using a common HTTP query (not like MBtiles or TPK which must be deployed into API Services to be able to be consumed by a webgis client). So, if you want to use Github as your host, you won't find an uploading problem because the file can be uploaded directly using GIT or Github Desktop. </div><div><br /></div><div>In this video, I will demonstrate how to write PMTiles from MBTiles (as far I know, there is no other </div><div>way to write PMTiles other than this way), then how to deploy it using Leaflet JS (other Web mapping frameworks should also be able to call PMTiles as long as they support tile layer). </div></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/_-d41I84oik" width="480"></iframe><div><br /></div><div><div>maybe you are asking is there any other way to generate MBTiles from raster/imagery data??, The answer is yes, there are many software that can do it. Here are some of them. </div><div><br /></div><div><b>MapTiler </b>- MapTiler is a popular tool for creating MBTiles from raster images. It is available both as a desktop application with a GUI and as a command-line tool. MapTiler can create MBTiles from a wide range of raster image formats, including GeoTIFF, JPEG, and PNG.</div><div><br /></div><div><b>GDAL </b>- GDAL (Geospatial Data Abstraction Library) is a powerful open-source software library that can be used to create MBTiles from raster images. GDAL provides command-line tools for converting raster images to MBTiles, such as gdal2tiles.py and gdal_translate.</div><div><br /></div><div><b>TileMill </b>- TileMill is an open-source map design studio that can be used to createMBTiles from raster images. It has a GUI that allows users to design maps using various data sources, including raster images. TileMill can also export maps to MBTiles.</div><div><br /></div><div><b>QGIS </b>- QGIS is a popular open-source GIS software that can be used to create MBTiles from raster images. QGIS provides a range of tools for working with raster data, including the ability to export maps to MBTiles.</div><div><br /></div><div><b>Mapbox Studio</b> - Mapbox Studio is a web-based tool for designing and publishing maps. It can be used to create MBTiles from raster images, as well as to design custom map styles and publish maps online.</div></div><div><br /></div><div><b>Global Mapper</b></div><div><div><br /></div><div><b>OpenMapTiles</b> - OpenMapTiles is an open-source project that provides tools for generating vector and raster tiles from OpenStreetMap data. It includes a tool called "generate-tiles" that can create MBTiles from raster images.</div><div><br /></div><div><b>Maperitive</b> - Maperitive is a free and open-source desktop application for creating custom maps. It can be used to create MBTiles from raster images, as well as to generate vector tiles and export maps in various formats.</div><div><br /></div><div><b>Kosmtik</b> - Kosmtik is a free and open-source tool for designing and publishing maps. It can be used to create MBTiles from raster images, as well as to style and export maps in various formats.</div><div><br /></div><div><b>TileStache</b> - TileStache is a Python-based server software for creating map tiles from various data sources, including raster images. It can be used to generate MBTiles and serve them as a map tile server.</div><div><br /></div><div><br /></div><div>and many more.</div></div>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-58387014659256422162023-04-08T17:20:00.001+07:002023-04-08T17:20:02.527+07:00HOW TO BUILD LOD2 3D BUILDING DATA USING LIDAR POINT CLOUD DATA IN ARCGIS PRO<div><div>1. The workflow demonstrated in this video uses ready-to-use LIDAR point cloud data, in that the </div><div>data has already undergone all of the LIDAR pre-processing steps up to point cloud classification. If </div><div>you have raw LIDAR or pre-classified LIDAR point clouds, I suggest you do the pre-processing and </div><div>point cloud classification first; there are many software programs that can do that. I also made one </div><div>video about it; just check my Agisoft Metashape Playlist.</div><div><br /></div><div>2. I am using ready-to-use LIDAR data from the USGS LIDAR 3DEP Portal at this URL: </div><div>https://apps.nationalmap.gov/lidar-explorer/#/; the data is available for free and no registration is </div><div>needed. Highly recommended data source for learning purposes.</div><div><br /></div><div>3. I am using ArcGIS Pro with an Advanced License and the 3D Analyst Extension for ArcGIS Pro; if </div><div>you don't have these prerequisites, I am afraid you wouldn't be able to practice the workflow I </div><div>demonstrated in this video.</div></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/82Ek8IPdZrk" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-44657391549229684442023-04-02T13:39:00.006+07:002023-04-02T13:39:45.738+07:00ArcGIS Online Basemaps Styles Customization Using ArcGIS Vector Tile Editor<div><br /></div><div>How to customize the ArcGIS basemaps styles, symbols, color, and other visualization properties using ArcGIS Vector Tile Editor. Customization result can be used in across of ArcGIS Family software such as ArcGIS Enterprise, ArcGIS Pro, even in QGIS and Geoserver. </div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/FhJnf3e51io" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-24127823901599794122023-03-26T00:15:00.005+07:002023-03-26T00:15:42.431+07:00SVG to GIS Vector Data Conversion and Vice Versa<div><span style="background-color: rgba(255, 255, 255, 0.1); font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;"><span style="color: #444444;">How to convert SVG (Scalable Vector Graphics) to GIS Vector Data (SHP or Mapinfo or any other format) using QGIS and Inkscape. GIS and Inkscape is a free and open source software that you can download from their respective site. </span></span></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/FUjgRRnR7r8" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-86458840257547664012023-03-22T01:20:00.008+07:002023-04-12T20:55:46.868+07:00How to Build HTML Form with Ability to Extract Geolocation Data From the Browser/Mobile Devices and Populate the Form Data in Google Sheets<span style="color: #f3f3f3;">Just as the post title suggest, this post is about how to do it. Here are the steps. </span><div><span style="color: #f3f3f3;"><br /></span></div><div><span style="color: #f3f3f3;"><br /></span></div><div><span style="color: #f3f3f3; font-size: medium;">1. Create a New Google Sheets Spreadsheet. Give a meaningful and consistent header such as the image below: </span></div><div><br /></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiXj5mqGp3GXjIalh_yEhPjSz3Dvw3Lns1avQEyVgRsm9lHLlAb_qv8JphuFQcu8vn_s1ZgqPYItIGIr4Hbe9kPNzXIUqCm8wZBjKwV7mu6ZRXsAjOikQlD5tSTg1vgxWC8FNELsbOAfJZ1vz0g4p8CmKvr_pHAG3jdUebaZq4sQXnplWD5bzG9OEuc" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="548" data-original-width="996" height="352" src="https://blogger.googleusercontent.com/img/a/AVvXsEiXj5mqGp3GXjIalh_yEhPjSz3Dvw3Lns1avQEyVgRsm9lHLlAb_qv8JphuFQcu8vn_s1ZgqPYItIGIr4Hbe9kPNzXIUqCm8wZBjKwV7mu6ZRXsAjOikQlD5tSTg1vgxWC8FNELsbOAfJZ1vz0g4p8CmKvr_pHAG3jdUebaZq4sQXnplWD5bzG9OEuc=w640-h352" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><span style="color: #f3f3f3; font-size: medium;">2. Share it as public (anyone with the link) and set the anyone as Editor. </span></div><div class="separator" style="clear: both; text-align: left;"><span style="color: #f3f3f3; font-size: medium;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="color: #f3f3f3; font-size: medium;">3. From the GSheets Menu, go to Extension > App Scripts. </span></div><div class="separator" style="clear: both; text-align: left;"><span style="color: #f3f3f3; font-size: medium;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="color: #f3f3f3; font-size: medium;">4. Delete the initial function, and copy/paste code snippets below. </span></div><br /><br /></div><br /></div>
<div class="code"><div style="background-color: #fffffe; color: #3c4043; font-family: "Roboto Mono", Consolas, "Courier New", monospace; font-size: 13px; line-height: 18px; white-space: pre;"><div><span style="color: #5f6368;">// Original code from https://github.com/jamiewilson/form-to-google-sheets</span></div><div><span style="color: #5f6368;">// Updated for 2021 and ES6 standards</span></div><br /><div><span style="color: #185abc;">const</span> <span style="color: #202124;">sheetName</span> = <span style="color: #b31412;">'Geolocation'</span></div><div><span style="color: #185abc;">const</span> <span style="color: #202124;">scriptProp</span> = <span style="color: #c92786;">PropertiesService</span>.<span style="color: #202124;">getScriptProperties</span>()</div><br /><div><span style="color: #185abc;">function</span> <span style="color: #202124;">initialSetup</span> () {</div><div> <span style="color: #185abc;">const</span> <span style="color: #202124;">activeSpreadsheet</span> = <span style="color: #c92786;">SpreadsheetApp</span>.<span style="color: #202124;">getActiveSpreadsheet</span>()</div><div> <span style="color: #202124;">scriptProp</span>.<span style="color: #202124;">setProperty</span>(<span style="color: #b31412;">'key'</span>, <span style="color: #202124;">activeSpreadsheet</span>.<span style="color: #202124;">getId</span>())</div><div>}</div><br /><div><span style="color: #185abc;">function</span> <span style="color: #202124;">doPost</span> (<span style="color: #202124;">e</span>) {</div><div> <span style="color: #185abc;">const</span> <span style="color: #202124;">lock</span> = <span style="color: #c92786;">LockService</span>.<span style="color: #202124;">getScriptLock</span>()</div><div> <span style="color: #202124;">lock</span>.<span style="color: #202124;">tryLock</span>(<span style="color: #098591;">10000</span>)</div><br /><div> <span style="color: #185abc;">try</span> {</div><div> <span style="color: #185abc;">const</span> <span style="color: #202124;">doc</span> = <span style="color: #c92786;">SpreadsheetApp</span>.<span style="color: #202124;">openById</span>(<span style="color: #202124;">scriptProp</span>.<span style="color: #202124;">getProperty</span>(<span style="color: #b31412;">'key'</span>))</div><div> <span style="color: #185abc;">const</span> <span style="color: #202124;">sheet</span> = <span style="color: #202124;">doc</span>.<span style="color: #202124;">getSheetByName</span>(<span style="color: #202124;">sheetName</span>)</div><br /><div> <span style="color: #185abc;">const</span> <span style="color: #202124;">headers</span> = <span style="color: #202124;">sheet</span>.<span style="color: #202124;">getRange</span>(<span style="color: #098591;">1</span>, <span style="color: #098591;">1</span>, <span style="color: #098591;">1</span>, <span style="color: #202124;">sheet</span>.<span style="color: #202124;">getLastColumn</span>()).<span style="color: #202124;">getValues</span>()[<span style="color: #098591;">0</span>]</div><div> <span style="color: #185abc;">const</span> <span style="color: #202124;">nextRow</span> = <span style="color: #202124;">sheet</span>.<span style="color: #202124;">getLastRow</span>() + <span style="color: #098591;">1</span></div><br /><div> <span style="color: #185abc;">const</span> <span style="color: #202124;">newRow</span> = <span style="color: #202124;">headers</span>.<span style="color: #202124;">map</span>(<span style="color: #185abc;">function</span>(<span style="color: #202124;">header</span>) {</div><div> <span style="color: #185abc;">return</span> <span style="color: #202124;">header</span> === <span style="color: #b31412;">'Date'</span> ? <span style="color: #185abc;">new</span> <span style="color: #c92786;">Date</span>() : <span style="color: #202124;">e</span>.<span style="color: #202124;">parameter</span>[<span style="color: #202124;">header</span>]</div><div> })</div><br /><div> <span style="color: #202124;">sheet</span>.<span style="color: #202124;">getRange</span>(<span style="color: #202124;">nextRow</span>, <span style="color: #098591;">1</span>, <span style="color: #098591;">1</span>, <span style="color: #202124;">newRow</span>.<span style="color: #202124;">length</span>).<span style="color: #202124;">setValues</span>([<span style="color: #202124;">newRow</span>])</div><br /><div> <span style="color: #185abc;">return</span> <span style="color: #c92786;">ContentService</span></div><div> .<span style="color: #202124;">createTextOutput</span>(<span style="color: #c92786;">JSON</span>.<span style="color: #202124;">stringify</span>({ <span style="color: #b31412;">'result'</span>: <span style="color: #b31412;">'success'</span>, <span style="color: #b31412;">'row'</span>: <span style="color: #202124;">nextRow</span> }))</div><div> .<span style="color: #202124;">setMimeType</span>(<span style="color: #c92786;">ContentService</span>.<span style="color: #c92786;">MimeType</span>.<span style="color: #c92786;">JSON</span>)</div><div> }</div><br /><div> <span style="color: #185abc;">catch</span> (<span style="color: #202124;">e</span>) {</div><div> <span style="color: #185abc;">return</span> <span style="color: #c92786;">ContentService</span></div><div> .<span style="color: #202124;">createTextOutput</span>(<span style="color: #c92786;">JSON</span>.<span style="color: #202124;">stringify</span>({ <span style="color: #b31412;">'result'</span>: <span style="color: #b31412;">'error'</span>, <span style="color: #b31412;">'error'</span>: <span style="color: #202124;">e</span> }))</div><div> .<span style="color: #202124;">setMimeType</span>(<span style="color: #c92786;">ContentService</span>.<span style="color: #c92786;">MimeType</span>.<span style="color: #c92786;">JSON</span>)</div><div> }</div><br /><div> <span style="color: #185abc;">finally</span> {</div><div> <span style="color: #202124;">lock</span>.<span style="color: #202124;">releaseLock</span>()</div><div> }</div><div>}</div></div></div><br /><span style="background-color: #444444; color: #f3f3f3;">Pay attention to <b>SheetName</b> constructor, the <b>SheetName </b>should be exactly matched with the Google Spreadsheet you are working on. </span><div><span style="background-color: white;"><br /></span></div><div><span style="background-color: #444444; color: #f3f3f3; font-size: medium;">5. Run the <b>Initial Setup </b>Function. Image description as follow. </span></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhtKfjkf-TxuzSnep4PYRi2BcQVHlL8Vtg4O0fl9QzAdoEVdGJ1Wg5-7yar_xk1sZTRkBcuKlyPvf4sLng6_OZo9iBiiUEFSBJET3FwBt_yYvDUpxcYZNosbHXAyNm870xCGmxZs3BUC4xvbw3haGJ2vL1KPhHtkMeyBIWvS_cuiTTVQ79iJhdWcELC" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="387" data-original-width="1012" height="244" src="https://blogger.googleusercontent.com/img/a/AVvXsEhtKfjkf-TxuzSnep4PYRi2BcQVHlL8Vtg4O0fl9QzAdoEVdGJ1Wg5-7yar_xk1sZTRkBcuKlyPvf4sLng6_OZo9iBiiUEFSBJET3FwBt_yYvDUpxcYZNosbHXAyNm870xCGmxZs3BUC4xvbw3haGJ2vL1KPhHtkMeyBIWvS_cuiTTVQ79iJhdWcELC=w640-h244" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">you will see a Prompt asking for permission, because<span> the S</span><span>cript has not been reviewed by Google, it will generate a warning before you can continue. You must click the "show advanced" text followed by click the "<Script Name>" for the script to have the correct permissions to update your </span><span><span>form. Sorry I don't have the image description, just message me if you are confused about this part. </span>Basically,<span> this is just similar permission prompt when you add new plugins or modules in your usual google workspace stuffs. If you are done on this step, continue with the step 6. </span></span></span></div><div class="separator" style="clear: both; text-align: left;"><span style="color: #24292f;"><span style="font-family: inherit;"><br /></span></span></div><div class="separator" style="clear: both; text-align: left;"><span style="color: #f3f3f3; font-size: medium;">6. Add <b>trigger </b>from the Script. </span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><span style="color: #24292f;"><br /></span></span></div><div class="separator" style="clear: both; text-align: left;"><p dir="auto" style="box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="background-color: #444444;"><span style="color: #f3f3f3;">Select the project "Triggers" from the sidebar and then click the <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Add Trigger</code> button.</span></span></p><p dir="auto" style="box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px;"><span style="background-color: #444444;"><span style="color: #f3f3f3;">In the show up window, select the following options:</span></span></p><ul dir="auto" style="box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 16px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="background-color: #444444;"><span style="color: #f3f3f3;">Choose which function to run: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">doPost</code></span></span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="background-color: #444444;"><span style="color: #f3f3f3;">Choose which deployment should run: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Head</code></span></span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="background-color: #444444;"><span style="color: #f3f3f3;">Select event source: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">From spreadsheet</code></span></span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="background-color: #444444;"><span style="color: #f3f3f3;">Select event type: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">On form submit</code></span></span></li></ul></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgbctZS8YGzm-6mqRuycO_iOme8yC7cREV6Nd24MaBSreWuira9xbn9FAj4ZdUMlJGwgB0JGL9k1IHzVKL_V5kBzUK5XMrUiwYWoX2YMhHWe7sWUdrUjwwoaoZqdgfhw67xEtXVLAAr_gyJUR3pl84nLrhcXLCYy64_2I-EMna0gfqfA-qOjJbDHo4w" style="margin-left: 1em; margin-right: 1em;"><img data-original-height="863" data-original-width="943" height="586" src="https://blogger.googleusercontent.com/img/a/AVvXsEgbctZS8YGzm-6mqRuycO_iOme8yC7cREV6Nd24MaBSreWuira9xbn9FAj4ZdUMlJGwgB0JGL9k1IHzVKL_V5kBzUK5XMrUiwYWoX2YMhHWe7sWUdrUjwwoaoZqdgfhw67xEtXVLAAr_gyJUR3pl84nLrhcXLCYy64_2I-EMna0gfqfA-qOjJbDHo4w=w640-h586" width="640" /></a></div><br /><div><span style="color: #f3f3f3;">then, Click <b>SAVE</b>. </span></div><div><br /></div><div><br /></div><div><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">7. Publish The Project </span></div><div><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;"><br /></span></div><div><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;"><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"">Now your project is ready to publish. Hit the </span><code style="border-radius: 6px; box-sizing: border-box; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Deploy</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji""> button and </span><code style="border-radius: 6px; box-sizing: border-box; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">New Deployment</code><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji""> from the drop-down.</span></span></div><div><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;"><br /></span></div><div><p dir="auto" style="box-sizing: border-box; margin-bottom: 16px; margin-top: 0px;"><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">Click the "Select type" icon and select <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Web app</code>.</span></p><p dir="auto" style="box-sizing: border-box; margin-bottom: 16px; margin-top: 0px;"><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">In the form that appears, select the following options:</span></p><ul dir="auto" style="box-sizing: border-box; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;"><li style="box-sizing: border-box;"><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">Description: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Geolocation</code> (The description text is free to modify as you want)</span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">Web app → Execute As: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Me</code></span></li><li style="box-sizing: border-box; margin-top: 0.25em;"><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">Web app → Who has access: <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Anyone</code></span></li></ul><p dir="auto" style="box-sizing: border-box; margin-bottom: 16px; margin-top: 0px;"><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">Then click <code style="background-color: var(--color-neutral-muted); border-radius: 6px; box-sizing: border-box; margin: 0px; padding: 0.2em 0.4em; white-space: break-spaces;">Deploy</code>.</span></p><p dir="auto" style="box-sizing: border-box; margin-bottom: 16px; margin-top: 0px;"><b><span style="background-color: #444444; color: #f3f3f3; font-family: inherit;">Save the Web App URL before you are moving to the next step. </span></b></p><div class="separator" style="clear: both;"><br /></div><div class="separator" style="clear: both;"><div><span style="color: #f3f3f3; font-size: medium;">8. Create The HTML Form. </span></div><div><span style="color: #f3f3f3;"><br /></span></div></div><div class="separator" style="clear: both;"><span style="color: #f3f3f3;">build your own HTML form as you wish, make it stylish with cool CSS if you want, give a fancy background and transparent effect as needed. However, the most important part is on the Input Field, make sure the <b>Input Name Tags </b>is matched with the<b> GSheets Headers.</b> </span></div><div class="separator" style="clear: both;"><span style="color: #f3f3f3;"><br /></span></div><div class="separator" style="clear: both;"><span style="color: #f3f3f3;"><b>second</b>, Add the Geolocation Request Function inside the <script> tags, and point the captured data to the HTML input fields, </span></div><div class="separator" style="clear: both;"><span style="color: #f3f3f3;"><br /></span></div><div class="separator" style="clear: both;"><span style="color: #f3f3f3;"><b>Third</b>, place the <b>Web App URL</b> in Step 7 to the <b>Form Action tag</b>. </span></div><div class="separator" style="clear: both;"><span style="color: #f3f3f3;"><br /></span></div><div class="separator" style="clear: both;"><span style="color: #f3f3f3;">Here is a simple HTML code example (deploy it in webserver such as XAMPP, WAMP or host it in public devs portal such as Github or any other service) to see how it works. Remember to put your <b>Web App URL in the Form Action</b>. <b>And Pay Attention to the Input Name in the Form, make sure they are exactly matched with the GSheets Headers Name. </b></span></div></div><div class="separator" style="clear: both;"><br /></div><br /></div><!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #557799;"><!DOCTYPE html></span>
<span style="color: #007700;"><html></span>
<span style="color: #007700;"><head></span>
<span style="color: #007700;"><meta</span> <span style="color: #0000cc;">charset=</span><span style="background-color: #fff0f0;">"UTF-8"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><title></span>Google Sheet Form<span style="color: #007700;"></title></span>
<span style="color: #007700;"><style></span>
<span style="color: #007700;">form</span> {
<span style="color: #008800; font-weight: bold;">display</span><span style="color: #333333;">:</span> flex;
flex<span style="color: #333333;">-</span><span style="color: #008800; font-weight: bold;">direction</span><span style="color: #333333;">:</span> column;
align<span style="color: #333333;">-</span>items<span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">center</span>;
gap<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1</span>rem;
}
<span style="color: #007700;">label</span> {
<span style="color: #008800; font-weight: bold;">font-weight</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">bold</span>;
}
<span style="color: #007700;">input</span><span style="color: #333333;">[</span><span style="color: #007700;">type</span><span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"text"</span><span style="color: #333333;">],</span>
<span style="color: #007700;">input</span><span style="color: #333333;">[</span><span style="color: #007700;">type</span><span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"email"</span><span style="color: #333333;">]</span> {
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">.</span><span style="color: #6600ee; font-weight: bold;">5</span>rem;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">2px</span> <span style="color: #008800; font-weight: bold;">solid</span> <span style="color: #007020;">gray</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">-</span>radius<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">.</span><span style="color: #6600ee; font-weight: bold;">5</span>rem;
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1</span>rem;
<span style="color: #008800; font-weight: bold;">width</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">100</span><span style="color: #333333;">%</span>;
}
<span style="color: #007700;">button</span><span style="color: #333333;">[</span><span style="color: #007700;">type</span><span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"submit"</span><span style="color: #333333;">]</span> {
<span style="color: #008800; font-weight: bold;">padding</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">.</span><span style="color: #6600ee; font-weight: bold;">5</span>rem;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">none</span>;
<span style="color: #008800; font-weight: bold;">border</span><span style="color: #333333;">-</span>radius<span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">0</span><span style="color: #333333;">.</span><span style="color: #6600ee; font-weight: bold;">5</span>rem;
<span style="color: #008800; font-weight: bold;">font-size</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">1</span>rem;
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">blue</span>;
<span style="color: #008800; font-weight: bold;">color</span><span style="color: #333333;">:</span> <span style="color: #007020;">white</span>;
<span style="color: #008800; font-weight: bold;">cursor</span><span style="color: #333333;">:</span> <span style="color: #008800; font-weight: bold;">pointer</span>;
}
<span style="color: #007700;">button</span><span style="color: #333333;">[</span><span style="color: #007700;">type</span><span style="color: #333333;">=</span><span style="background-color: #fff0f0;">"submit"</span><span style="color: #333333;">]</span><span style="color: #555555; font-weight: bold;">:hover</span> {
<span style="color: #008800; font-weight: bold;">background-color</span><span style="color: #333333;">:</span> <span style="color: #007020;">darkblue</span>;
}
<span style="color: #007700;"></style></span>
<span style="color: #007700;"><script></span>
<span style="color: #008800; font-weight: bold;">function</span> getLocation() {
<span style="color: #888888;">// Check if the browser supports geolocation</span>
<span style="color: #008800; font-weight: bold;">if</span> (navigator.geolocation) {
<span style="color: #888888;">// Get the current position of the user</span>
navigator.geolocation.getCurrentPosition(showPosition);
} <span style="color: #008800; font-weight: bold;">else</span> {
alert(<span style="background-color: #fff0f0;">"Geolocation is not supported by this browser."</span>);
}
}
<span style="color: #008800; font-weight: bold;">function</span> showPosition(position) {
<span style="color: #888888;">// Get the latitude and longitude values from the geolocation data</span>
<span style="color: #008800; font-weight: bold;">var</span> latitude <span style="color: #333333;">=</span> position.coords.latitude;
<span style="color: #008800; font-weight: bold;">var</span> longitude <span style="color: #333333;">=</span> position.coords.longitude;
<span style="color: #888888;">// Populate the input field with the latitude and longitude values</span>
<span style="color: #007020;">document</span>.getElementById(<span style="background-color: #fff0f0;">"Latitude"</span>).value <span style="color: #333333;">=</span> latitude;
<span style="color: #007020;">document</span>.getElementById(<span style="background-color: #fff0f0;">"Longitude"</span>).value <span style="color: #333333;">=</span> longitude;
}
<span style="color: #007700;"></script></span>
<span style="color: #007700;"></head></span>
<span style="color: #007700;"><body></span>
<span style="color: #007700;"><form</span> <span style="color: #0000cc;">action=</span><span style="background-color: #fff0f0;">"<b>YOUR WEBAPP URL</b>"</span> <span style="color: #0000cc;">method=</span><span style="background-color: #fff0f0;">"post"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"Email"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"email"</span> <span style="color: #0000cc;">placeholder=</span><span style="background-color: #fff0f0;">"Email"</span> <span style="color: #0000cc;">required</span><span style="color: #007700;">></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"Name"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"text"</span> <span style="color: #0000cc;">placeholder=</span><span style="background-color: #fff0f0;">"Name"</span> <span style="color: #0000cc;">required</span><span style="color: #007700;">></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"Description"</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"text"</span> <span style="color: #0000cc;">placeholder=</span><span style="background-color: #fff0f0;">"Description"</span> <span style="color: #0000cc;">required</span><span style="color: #007700;">></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"text"</span> <span style="color: #0000cc;">id=</span><span style="background-color: #fff0f0;">"Latitude"</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"Latitude"</span> <span style="color: #0000cc;">placeholder=</span><span style="background-color: #fff0f0;">"Latitude"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><input</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"text"</span> <span style="color: #0000cc;">id=</span><span style="background-color: #fff0f0;">"Longitude"</span> <span style="color: #0000cc;">name=</span><span style="background-color: #fff0f0;">"Longitude"</span> <span style="color: #0000cc;">placeholder=</span><span style="background-color: #fff0f0;">"Longitude"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><button</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"button"</span> <span style="color: #0000cc;">onclick=</span><span style="background-color: #fff0f0;">"getLocation()"</span><span style="color: #007700;">></span>Get Location<span style="color: #007700;"></button></span>
<span style="color: #007700;"><button</span> <span style="color: #0000cc;">type=</span><span style="background-color: #fff0f0;">"submit"</span><span style="color: #007700;">></span>Send<span style="color: #007700;"></button></span>
<span style="color: #007700;"></form></span>
<span style="color: #007700;"></body></span>
<span style="color: #007700;"></html></span>
</pre></div>
<br /><br /><div><span style="color: #f3f3f3;">The form will look like this below.</span><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE0PlO2JTNRny1b-5qHZVcjWeKZ8xr55UZAfGiuGypBUd_fLokvIOpGT3Z9hYR6AFeNDuYongZ0m3SpxqsBI8YxsSnRiphoaYhd4Hq2Fedr1i1cwv5qFtqa3Y2NXtBBrg2QbQtj_G0EGrYbXE5K1dztOH6kpUIkZ7hvgzhX9epjodnSBKzhfyGhcTN/s1831/geo2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="607" data-original-width="1831" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE0PlO2JTNRny1b-5qHZVcjWeKZ8xr55UZAfGiuGypBUd_fLokvIOpGT3Z9hYR6AFeNDuYongZ0m3SpxqsBI8YxsSnRiphoaYhd4Hq2Fedr1i1cwv5qFtqa3Y2NXtBBrg2QbQtj_G0EGrYbXE5K1dztOH6kpUIkZ7hvgzhX9epjodnSBKzhfyGhcTN/w640-h212/geo2.png" width="640" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><span style="color: #f3f3f3;">When you hit the Get Location Button, browser or device will ask about your device location, if you approve it, latitude and longitude values will automatically be populated in the respective fields, all other fields can be typed manually, when you are done, hit the Send button, the data will be send to GSheets. </span><br /><br /><div><br /></div><div><b><span style="color: #f3f3f3;">Here is the example of inputted data in GSheets</span></b></div><div><b><span style="color: #f3f3f3;"><br /></span></b></div><div><span style="color: #f3f3f3;"><div class="separator" style="clear: both; font-weight: bold; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><br /></div><div class="separator" style="clear: both; font-weight: bold; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh09S7eRJNEH3lhYCHy3zO9MnFuMWzQ99sXnf4bAoSN4Ufl4PgRtzF5xMNm64fxpmhF_EbdMyrf6v3A3wZ_Osx3BCMvah_FdTtiy_AW4keM7kHlJPm0TBZA6MmSQSvtZZWq2z94TOU8X45SZuF-Bju0C5a_J2TVAvWydo3UDXWWA3ISL0-VimC_lDCw/s1009/geo.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="364" data-original-width="1009" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh09S7eRJNEH3lhYCHy3zO9MnFuMWzQ99sXnf4bAoSN4Ufl4PgRtzF5xMNm64fxpmhF_EbdMyrf6v3A3wZ_Osx3BCMvah_FdTtiy_AW4keM7kHlJPm0TBZA6MmSQSvtZZWq2z94TOU8X45SZuF-Bju0C5a_J2TVAvWydo3UDXWWA3ISL0-VimC_lDCw/w640-h230/geo.png" width="640" /></a></div><br /><br /><b>by these methods, you can design the forms in a very flexible way, and you can make it beauty using CSS while not losing the important functions. </b></span></div><div><b><span style="color: #f3f3f3;"><br /></span></b></div><div><b><span style="color: #f3f3f3;"><br /></span></b></div><div><b><span style="color: #f3f3f3;">Cheers. </span></b></div></div></div><div><b><span style="color: #f3f3f3;"><br /></span></b></div><div><b><span style="color: #f3f3f3;">If you prefer a video tutorial about this workflow, here is below</span></b></div><div><b><span style="color: #f3f3f3;"><br /></span></b></div><div><b><span style="color: #f3f3f3;"><br /></span></b></div><iframe width="560" height="315" src="https://www.youtube.com/embed/FQJ0vQ4UuUM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-12373845994581154382023-02-19T10:13:00.002+07:002023-02-19T10:13:23.682+07:00Extracting Google Maps Route as GIS Data<h3 style="text-align: left;"><span style="background-color: white; font-family: Roboto, Noto, sans-serif; font-size: 15px; white-space: pre-wrap;">How to extract Google Maps Route as GIS Data in GPX Format using maptogpx.com , </span></h3><div><span style="background-color: #282828; color: white; font-family: Roboto, Noto, sans-serif; font-size: 15px; white-space: pre-wrap;"><br /></span></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/ON4BqQBzo38" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-56773153727177783192023-02-14T16:56:00.006+07:002023-02-14T16:56:59.937+07:00Convert Multiple GIS Shapefiles to Single DXF CAD<div><b><br /></b></div><div><span style="background-color: rgba(255, 255, 255, 0.1); font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;"><b>How to convert multiple GIS Layers (in shapefile or other GIS formats) to Single DXF CAD file. This workflow can be done in QGIS A free Geographic Information System Software, and may be useful for certain data management workflow or GIS-CAD Integration.
</b></span></div><div><span style="background-color: rgba(255, 255, 255, 0.1); color: #f1f1f1; font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;"><br /></span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/PSFv16217Fw" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-89555198434158913732022-09-14T10:55:00.004+07:002022-09-14T10:55:47.341+07:00How to make 3D Elevation Profile in ArcGIS Pro<div>How to make 3D Elevation profile in ArcGIS Pro. There are two ways how to do it. First is using Profile Graph and Profile Geoprocessing Tool, and for the second is using Elevation profile Tool from Global/Local Scene Exploratory 3D Elevation Profile Tool. Below is the complete tutorial about how to do for both methods. </div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/5Xe8TWJ3qaY" style="background-image: url(https://i.ytimg.com/vi/5Xe8TWJ3qaY/hqdefault.jpg);" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-52399737569840724602022-09-08T13:43:00.003+07:002022-09-08T13:43:29.377+07:00Using Github as Raster Tile Server<div><span style="background-color: white; font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;">How to use Github to host raster tiles geospatial data like imagery or map. TMS and XYZ Tiles protocol are supported. The output tiles can be consumed by LeafjetJS, ArcGIS JS API, Mapbox JS, OpenLayers or any other webmapping Javascript Framework as long as they are support TMS or XYZ tiles</span></div><div><br /></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/WsCWCZJNRrQ" style="background-image: url(https://i.ytimg.com/vi/WsCWCZJNRrQ/hqdefault.jpg);" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-13408204240477032522022-09-05T13:38:00.002+07:002022-09-05T13:38:18.662+07:00Improve Sentinel 2 Imagery Spatial Resolution Using SEN2RES Plugin in ESA SNAP<div><span style="background-color: white; font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;">How to improve the spatial resolution of Sentinel-2 Imagery 60 meters and 20 meters resolution to 10 meters without sacrifing the spectral information, using SEN2RES Plugin, </span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/7k73xjDlPbg" style="background-image: url(https://i.ytimg.com/vi/7k73xjDlPbg/hqdefault.jpg);" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-39234353742028068132022-09-03T23:59:00.003+07:002022-09-03T23:59:33.780+07:00Convert ArcGIS Pro Map to Adobe Illustrator and Adobe Photoshop<div><span style="background-color: white; font-family: Roboto, Noto, sans-serif; font-size: 15px; white-space: pre-wrap;">How to convert ArcGIS Pro Layouted Maps into Adobe Illustrator and Adobe Photoshop format while maintain and preserve the layers structure, texts, graphics, rasters, and other elements. Basically this video is about how to maintain the exported data are not flattened. </span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/RjH7ErURiic" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0tag:blogger.com,1999:blog-4889724675331462317.post-39084577641023742252022-08-31T14:19:00.001+07:002022-08-31T14:19:11.426+07:00Convert QGIS Map to Adobe Illustrator and Adobe Photoshop<div><span style="background-color: white; font-family: Roboto, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;">How to convert QGIS Maps to Adobe Illustrator and Adobe Photoshop for futher advanced map design, geovisualization, and advanced cartography. </span></div><div><br /></div><iframe frameborder="0" height="270" src="https://youtube.com/embed/cBT-HSguG5c" width="480"></iframe>geo2004http://www.blogger.com/profile/00233221980225301312noreply@blogger.com0