Commit f8f4fc1f authored by theopolisme's avatar theopolisme
Browse files

Merge branch 'master' into gh-pages

parents 933f782c ba283209
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -16,10 +16,11 @@
            <!-- Intro, before data has been uploaded -->
            <div id="intro" class="content-box">
                <h2>location-history-visualizer</h2>
                <p class="whats-new"><b>What's new:</b> 1000x faster processing time, heatmap controls, and more!</p>
                <p>Welcome to <b>location-history-visualizer</b>, a tool for visualizing your collected Google <a href="https://google.com/locationhistory" target="_blank">Location History</a> data with heatmaps. <i>Don't worry&mdash;all processing and visualization happens directly on your computer, so rest assured that nobody is able to access your Location History but you... and Google, of course.</i> ^.^</p>
                <p>To start off, you'll need to go to <a href="https://google.com/takeout" target="_blank">Google Takeout</a> to download your Location History data: on that page, deselect everything except Location History by clicking "Select none" and then reselecting "Location History". Then hit "Next" and, finally, click "Create archive". Once the archive has been created, click "Download". Unzip the downloaded file, and open the "Location History" folder within. <b>Then, drag and drop <i>LocationHistory.json</i> from inside that folder onto this page.</b> Let the visualization begin!</p>
                <p class="fallback">Alternatively, select your <b>LocationHistory.json</b> file directly: <input name="file" type="file" id="file"></input></p>
                <hr>
                <p><i>Experimental (even faster!) import method:</i> Instead of going through Google Takeout, simply browse to the <a href="https://maps.google.com/locationhistory/kml?startTime=0&endTime=9000000000000" target="_blank">Google Location History KML API endpoint</a>. A file (<b>history-12-31-1969.kml</b>) will be downloaded &ndash; just drag and drop it onto this page, and we're off! <i>Note:</i> This uses a non-public Google API and as such may cease to work at any point. Your mileage may vary.</p>
                <p class="credit">A project by <a href="http://theopolis.me" target="_blank">@theopolisme</a>. Made in 2014 in Memphis, Tennessee.</p>
            </div>

@@ -40,7 +41,7 @@
            <div id="done" class="content-box hidden">
                <h2>Render complete!</h2>
                <p>Successfully processed <span id="numberProcessed"></span> data points to generate the heatmap. Click inside this box to dismiss it and start exploring...</p>
                <p><i>Zoom</i> by scrolling, double-clicking, or using the buttons in the upper lefthand corner. <i>Navigate</i> by clicking and dragging.</p>
                <p><i>Zoom</i> by scrolling, double-clicking, or using the buttons in the upper lefthand corner. <i>Navigate</i> by clicking and dragging. Hover over the menu in the lower lefthand corner to customize the heatmap rendering.</p>
                <p class="credit">A project by <a href="http://theopolis.me" target="_blank">@theopolisme</a>. Made in 2014 in Memphis, Tennessee.</p>
            </div>
        </div>
+44 −18
Original line number Diff line number Diff line
@@ -9,8 +9,6 @@
	// Start at the beginning
	stageOne();

	////// STAGE 1 - ZE VELCOME UNT ZE UPLOAD //////

	function stageOne () {
		var dropzone;

@@ -40,11 +38,8 @@
		} );
	}

	////// STAGE 2 - ZE PROCESSING //////

	function stageTwo ( file ) {
		heat = L.heatLayer( [], heatOptions ).addTo( map ),
			SCALAR_E7 = 0.0000001; // Since Google Takeout stores latlngs as integers
		heat = L.heatLayer( [], heatOptions ).addTo( map );

		// First, change tabs
		$( 'body' ).addClass( 'working' );
@@ -64,32 +59,63 @@

			status( 'Preparing to import file (' + fileSize + ')...' );

			function getLocationDataFromJson ( data ) {
				var SCALAR_E7 = 0.0000001, // Since Google Takeout stores latlngs as integers
					locations = JSON.parse( data ).locations;

				if ( !locations || locations.length === 0 ) {
					throw new ReferenceError( 'No location data found.' );
				}

				return locations.map( function ( location ) {
					return [ location.latitudeE7 * SCALAR_E7, location.longitudeE7 * SCALAR_E7 ];
				} );
			}

			function getLocationDataFromKml ( data ) {
				var KML_DATA_REGEXP = /<when>(.*?)<\/when>\s*<gx:coord>(\S*)\s(\S*)\s(\S*)<\/gx:coord>/g,
					locations = [],
					match = KML_DATA_REGEXP.exec( data );

				// match
				//  [1] ISO 8601 timestamp
				//  [2] longitude
				//  [3] latitude
				//  [4] altitude (not currently provided by Location History)

				while ( match !== null ) {
					locations.push( [ Number( match[3] ), Number( match[2] ) ] );
					match = KML_DATA_REGEXP.exec( data );
				}

				return locations;
			}

			reader.onprogress = function ( e ) {
				var percentLoaded = Math.round( ( e.loaded / e.total ) * 100 );
				status( percentLoaded + '% of ' + fileSize + ' loaded...' );
			};

			reader.onload = function ( e ) {
				var locations;
				var latlngs;

				status( 'Generating map...' );

				try {
					locations = JSON.parse( e.target.result ).locations;
					if ( !locations || locations.length === 0 ) {
						throw new ReferenceError( 'No location data found.' );
					if ( /.kml$/.test( file.name ) ) {
						latlngs = getLocationDataFromKml( e.target.result );
					} else {
						latlngs = getLocationDataFromJson( e.target.result );
					}
				} catch ( ex ) {
					status( 'Something went wrong generating your map. Ensure you\'re uploading a Google Takeout JSON file that contains location data and try again, or create an issue on GitHub if the problem persists. (error: ' + ex.message + ')' );
					return;
				}

				heat._latlngs = locations.map( function ( location ) {
					return [ location.latitudeE7 * SCALAR_E7, location.longitudeE7 * SCALAR_E7 ];
				} );
				heat._latlngs = latlngs;

				heat.redraw();
				stageThree( /* numberProcessed */ locations.length );
				stageThree( /* numberProcessed */ latlngs.length );
			};

			reader.onerror = function () {
@@ -100,8 +126,6 @@
		}
	}

	////// STAGE 3 - THEY GROW UP SO FAST //////

	function stageThree ( numberProcessed ) {
		var $done = $( '#done' );

@@ -128,8 +152,10 @@
			function updateInputs () {
				var option;
				for ( option in heatOptions ) {
					if ( heatOptions.hasOwnProperty( option ) ) {
						document.getElementById( option ).value = heatOptions[option];
				};
					}
				}
			}

			updateInputs();