<!DOCTYPE html><html><head> <title>What is your current home address?</title> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" /> <style> #map { height: 600px; width: 100%; } #search-box { margin-bottom: 10px; } .error-message { color: red; font-weight: bold; display: none; } span, input, button { font-size: 18px; } .parcel-label { background-color: transparent !important; border: none !important; box-shadow: none !important; font-weight: bold; color: black; } </style></head><body> <strong style="font-size: 20px;">What is your current home address?</strong> <div> <br /> <span style="font-size: 20px;">To select your home address, you may either click on a property or enter an address in the search bar. Once you select a location, a pin will appear in the center of the selected property, indicating that the location has been marked. The properties will only appear once the map is zoomed in and will disappear when zoomed out.</span> </div> <div id="search-box"> <input type="text" id="address-input" placeholder="Enter address" /> <button onclick="geocodeAddress()">Search</button> </div> <div id="map"></div> <div id="error-message">Please select a location by clicking or searching!</div>
<!-- Required libraries --> <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> <script src="https://unpkg.com/esri-leaflet@3.0.4/dist/esri-leaflet.js"></script> <script src="https://unpkg.com/@turf/turf/turf.min.js"></script> <!-- Replace with your own Google Maps API key --> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_API_KEY_HERE&libraries=places"></script>
<script> // Initialize map centered on Santa Barbara, CA var map = L.map('map').setView([34.4208, -119.6982], 13); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map);
var marker = null; var polygonsVisible = false;
// Set up address autocomplete const addressInput = document.getElementById('address-input'); const autocomplete = new google.maps.places.Autocomplete(addressInput);
autocomplete.addListener('place_changed', function () { const place = autocomplete.getPlace(); if (place.geometry) { const latLng = { lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }; moveMarker(latLng, true); } });
// Save selected location as Qualtrics embedded data function updateCoordinates(latLng) { Qualtrics.SurveyEngine.setEmbeddedData('droppedMarkerLat', latLng.lat); Qualtrics.SurveyEngine.setEmbeddedData('droppedMarkerLng', latLng.lng); Qualtrics.SurveyEngine.setEmbeddedData('LocationMarked', 'true'); }
// Drop or move a marker, recenter map, check for polygon match function moveMarker(latLng, forceZoomIn = false) { if (marker) { marker.setLatLng(latLng); } else { marker = L.marker(latLng, { draggable: true }).addTo(map); marker.on('moveend', function (e) { const newLatLng = e.target.getLatLng(); updateCoordinates(newLatLng); if (map.getZoom() < 17) { map.setView(newLatLng, 17); } checkPolygon(newLatLng); }); }
updateCoordinates(latLng); if (forceZoomIn && map.getZoom() < 17) { map.setView(latLng, 17); } else if (forceZoomIn) { map.panTo(latLng); }
checkPolygon(latLng); }
// Define parcel polygon layer (replace with your own FeatureServer URL) const buildingLayer = L.esri.featureLayer({ url: 'YOUR_FEATURE_LAYER_URL_HERE', style: () => ({ color: "#0000FF", weight: 0.5, opacity: 1, fillColor: "#0000FF", fillOpacity: 0.1 }), onEachFeature: function (feature, layer) { const code = feature.properties?.parcel_cod || ""; const centroidCoords = turf.centroid(feature).geometry.coordinates; const centroidLatLng = [centroidCoords[1], centroidCoords[0]];
layer.bindTooltip(code, { permanent: true, direction: 'center', className: 'parcel-label' }).openTooltip();
layer.on('click', function (e) { moveMarker(e.latlng, true); }); } });
// Identify if clicked point intersects any polygon; store keys as Qualtrics data function checkPolygon(latLng) { if (map.getZoom() < 15) return;
buildingLayer.query().contains(L.latLng(latLng.lat, latLng.lng)).run(function (error, featureCollection) { if (error) return;
if (featureCollection.features.length > 0) { const feature = featureCollection.features[0]; if (!feature.properties || !feature.properties.key_) return;
const selectedKey = feature.properties.key_.trim(); const selectedKeyFirst = feature.properties.keyfirst?.trim() || ""; const selectedKeySecond = feature.properties.keysecond?.trim() || "";
Qualtrics.SurveyEngine.setEmbeddedData('selectedKey', selectedKey); Qualtrics.SurveyEngine.setEmbeddedData('selectedKeyFirst', selectedKeyFirst); Qualtrics.SurveyEngine.setEmbeddedData('selectedKeySecond', selectedKeySecond);
const centroid = turf.centroid(feature.geometry); const centroidLatLng = { lat: centroid.geometry.coordinates[1], lng: centroid.geometry.coordinates[0] }; if (marker) marker.setLatLng(centroidLatLng); } else { Qualtrics.SurveyEngine.setEmbeddedData('selectedKey', ''); Qualtrics.SurveyEngine.setEmbeddedData('selectedKeyFirst', ''); Qualtrics.SurveyEngine.setEmbeddedData('selectedKeySecond', ''); } }); }
// Show/hide parcel layer depending on zoom and polygon size function toggleLayerVisibility() { const zoomLevel = map.getZoom(); let zoomThreshold = 17;
buildingLayer.query().within(map.getBounds()).run(function (error, featureCollection) { if (error) return;
if (featureCollection.features.length > 0) { let totalArea = 0; featureCollection.features.forEach(feature => { const area = turf.area(feature.geometry); totalArea += area; }); const avgArea = totalArea / featureCollection.features.length;
if (avgArea > 10000) { zoomThreshold = 14; } else if (avgArea > 1000) { zoomThreshold = 17; } else { zoomThreshold = 17; } }
if (zoomLevel >= zoomThreshold && !polygonsVisible) { map.addLayer(buildingLayer); polygonsVisible = true; } else if (zoomLevel < zoomThreshold && polygonsVisible) { map.removeLayer(buildingLayer); polygonsVisible = false; } }); }
map.on('zoomend moveend', function () { toggleLayerVisibility(); if (marker && map.getZoom() >= 15) { checkPolygon(marker.getLatLng()); } });
// Prevent user from submitting without selecting a location Qualtrics.SurveyEngine.addOnPageSubmit(function () { if (!Qualtrics.SurveyEngine.getEmbeddedData('LocationMarked')) { Qualtrics.SurveyEngine.setEmbeddedData('LocationMarked', 'false'); document.getElementById('error-message').style.display = 'block'; } else { document.getElementById('error-message').style.display = 'none'; } });
// Search and place marker based on address string function geocodeAddress() { const address = document.getElementById('address-input').value; if (!address) return;
const geocoder = new google.maps.Geocoder(); geocoder.geocode({ address: address }, function (results, status) { if (status === 'OK') { const location = results[0].geometry.location; const latLng = { lat: location.lat(), lng: location.lng() }; moveMarker(latLng, true); } else { alert("Geocode was not successful for the following reason: " + status); } }); } </script></body></html>