If I knew when, where, and what I tweeted, I thought it would be fun like a life log, so I made a "tweet map".
This is my first time to touch both Google Maps API and Twtter API. Thank you for your help on various sites. .. .. ..
⬆️ This is when I ride a bicycle on the Shimanami Kaido (It's fun to know where and what you're doing! It's personal information!)
PC: MacBook Air (Retina, 13-inch, 2018) OS: macOS Mojave (ver 10.14.1) Processor: 1.6 GHz Intel Core i5 Memory: 16 GB 2133 MHz LPDDR3 Editor: Visual Studio Code
This time, we will download the movement history from the location history of Google Map and use it. In addition, the content of the tweet is acquired using the Twitter API. Data download and registration are required for each.
For how to get the location history, refer to here. Download Google Map History (timeline)
Extract Google Maps action log
For the registration method required when using the Google Masp API, refer to here. I tried using the Google Maps API
For the registration method of Twitter API, refer to here. Summary of steps from Twitter API registration (account application method) to approval
Since the location history data is in json format and it seems convenient to match the file format, prepare the tweet data in json format (tweet_timeline.json) as well.
(This time I wanted to use a library called tweepy, so I wrote it in python.)
get_tweet_data.py
import tweepy
import json
import time
import calendar
#Consumer key and access token settings for using Twitter API
Consumer_key = '<API key obtained by applying for Twitter API registration>'
Consumer_secret = '<Consumer obtained by applying for Twitter API registration_secret>'
Access_token = '<Access obtained by applying for Twitter API registration_token>'
Access_secret = '<Access obtained by applying for Twitter API registration_secret>'
#Authentication
auth = tweepy.OAuthHandler(Consumer_key, Consumer_secret)
auth.set_access_token(Access_token, Access_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)
#Tweet data array
tweet_data = []
#Acquisition account Account name@Enter the name excluding
user = "******"
#json data creation
for tweet in tweepy.Cursor(api.user_timeline, screen_name=user, exclude_replies=True, include_entities=True).items():
#Convert twitter API tweet time to UNIX
tweet_utc_time = time.strptime(
str(tweet.created_at), "%Y-%m-%d %H:%M:%S")
tweet_unix_time = calendar.timegm(tweet_utc_time)
#If there is an image, add the URL element of the image
if 'media' in tweet.entities:
for media in tweet.entities['media']:
tweet_image_url = media['media_url_https']
#Added image element to tweet data array
tweet_data.append({
"id": tweet.id, "created_at": tweet_unix_time, "text": tweet.text,
"fav": tweet.favorite_count, "RT": tweet.retweet_count, "image": tweet_image_url
})
else:
#Add element to tweet data array
tweet_data.append({
"id": tweet.id, "created_at": tweet_unix_time, "text": tweet.text,
"fav": tweet.favorite_count, "RT": tweet.retweet_count
})
tweet_dict = {"timeline": tweet_data}
#json file name
fw = open('tweet_timeline.json', 'w')
#json file output json.Write to a file with the dump function
json.dump(tweet_dict, fw, indent=4, ensure_ascii=False)
Since the Twitter API can take time in a special format, it is converted to Unix time to match the location history, and the image data is also summarized in a json file in an easy-to-use format.
After that, use the prepared location history and Tweet data to map the coordinates and Tweet data, and you're done. Since we use GoogleMapsAPI, we use javascript, html, css.
Thank you very much for your help on this site. .. .. It is almost a copy level. .. Place markers from json data with Google Maps API
sample.js
const START_DAY = '2019/4/7';
const END_DAY = '2019/4/8';
const POINTS = 1;
var date;
var ready = { api: false, ajax: false };
var map;
var mapData;
var mapOptions = {
center: { //Map latitude and longitude
lat: 35.700000,
lng: 139.772000
},
zoom: 17, //Map magnification
scrollwheel: false, //Whether to scale by wheel operation
mapTypeControl: false, //Whether to show map switching controls
streetViewControl: false //Whether to show Street View controls
}
var latlngs = [];
var tweetdata;
var infoWindowIndex = [];
var startDay = new Date(START_DAY);
var unixTimestampstartDay = Math.round(startDay.getTime());
console.log(unixTimestampstartDay)
var endDay = new Date(END_DAY);
var unixTimestampendDay = Math.round(endDay.getTime())
console.log(unixTimestampendDay)
var aveLat = 0;
var aveLng = 0;
$(function () {
$.ajax({
url: 'tweet_timeline.json',
dataType: 'json',
cache: false
})
.then(
function (data) {
console.log('I succeeded in getting the Twitter timeline.');
tweetData = data["timeline"];
ready['ajax'] = true;
},
function () {
console.log('Failed to get the Twitter timeline.');
}
);
});
$(function () {
$.ajax({
url: 'Location history.json',
dataType: 'json',
cache: false
})
.then(
function (data) {
console.log('You have succeeded in acquiring location information.');
mapData = data["locations"];
ready['ajax'] = true;
generate_map();
},
function () {
console.log('Failed to get the location information.');
}
);
});
/**
*What to do after the Google Maps API is ready
*/
function api_ready() {
ready['api'] = true;
generate_map();
}
/**
*Generate a map
*/
function generate_map() {
if (ready['api'] && ready['ajax']) {
map = new google.maps.Map(document.getElementById('map'), {
//Zoom level
zoom: 10,
//Center point latitude / longitude
center: new google.maps.LatLng(mapData[0].latitudeE7 * 0.0000001, mapData[0].longitudeE7 * 0.0000001),
//Distance scale display
scaleControl: true,
//Map type
mapTypeId: google.maps.MapTypeId.ROADMAP
});
add_marker();
generate_polyline();
}
}
/**
*Add markers to the map
*/
function add_marker() {
var markerNum = 0;
var j = 0;
var infoWindowNum = 0;
for (var i = 0; i < mapData.length; i += POINTS) {
var item = mapData[i];
if (startDay <= item.timestampMs && item.timestampMs <= endDay) {
date = new Date(Number(item.timestampMs));
latlngs.push(new google.maps.LatLng(item.latitudeE7 * 0.0000001, item.longitudeE7 * 0.0000001));
//Generate speech bubbles
var ins = '<div class="map-window">';
ins += '<font size="2">'
//ins += '<p class="map-window_name">' + date + '</p>';
var flag = 0;
var tw = 0;
var itemNext = mapData[i + POINTS];
//Reflect the Tweet content in the balloon
for (var j = 0; j < tweetData.length; j++) {
if (item.timestampMs <= (tweetData[j].created_at * 1000) && (tweetData[j].created_at * 1000) < itemNext.timestampMs) {
console.log(date);
console.log(tweetData[j].text);
ins += '<p class="map-window_name">' + tweetData[j].text + '</p>';
//Key to associative array"image"If there is, add an image
if (tweetData[j].image) {
ins += "<img src='" + tweetData[j].image + ":thumb'></br >";
}
tw = 1;
}
}
ins += '</font>';
ins += '</div>';
//Generate balloons only for markers with Tweet
if (tw == 1) {
//Installation of markers
var marker = new google.maps.Marker({
position: latlngs[markerNum],
map: map,
animation: google.maps.Animation.DROP,
});
var infoWindow = new google.maps.InfoWindow({
content: ins
});
infoWindowIndex[infoWindowNum] = i;
infoWindowNum++;
//Marker event settings
add_event_to_marker(marker, infoWindow, i);
}
aveLat += (item.latitudeE7 * 0.0000001);
aveLng += (item.longitudeE7 * 0.0000001)
markerNum++;
}
}
//Set the average of the coordinates to the center of the map
aveLat /= markerNum;
aveLng /= markerNum;
map.setCenter(new google.maps.LatLng(aveLat, aveLng));
}
/**
*Add an event to the marker
* @param {object} marker (required)Marker information
* @param {object} infoWindow (required)Information on balloons
* @param {number} index (required)Map information index number
*/
function add_event_to_marker(marker, infoWindow, index) {
var item = mapData[index];
item['marker'] = marker;
item['infoWindow'] = infoWindow;
item['infoWindow'].open(map, item['marker']);
//Display a balloon when the marker is clicked
item['marker'].addListener('click', function (e) {
infoWindows_hide();
item['infoWindow'].open(map, item['marker']);
});
}
/**
*Hide the callout
*/
function infoWindows_hide() {
for (var i = 0; i < infoWindowIndex.length; i++) {
if (startDay <= mapData[infoWindowIndex[i]]['timestampMs'] && mapData[infoWindowIndex[i]]['timestampMs'] <= endDay)
mapData[infoWindowIndex[i]]['infoWindow'].close();
}
}
/**Display balloons in order*/
function infoWindows_open() {
var j = 0;
for (var i = 0; i < mapData.length; i++) {
if (infoWindowIndex[j] == i) {
mapData[i]['infoWindow'].open(map, mapData[i]['marker']);
j++;
}
}
}
/**Generate a polyline*/
function generate_polyline() {
//Draw a line
lines = new google.maps.Polyline({
path: latlngs,
strokeColor: "#8a2be2",
strokeOpacity: .7,
strokeWeight: 5
});
lines.setMap(map);
}
map.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Tweet map</title>
<link rel="stylesheet" href="sample.css" />
</head>
<body>
<div id="map"></div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="./sample.js"></script>
<script
src="https://maps.googleapis.com/maps/api/js?key=<Prepared GCP key>&callback=api_ready"></script>
</body>
</html>
sample.css
#map {
width: 1000px;
height: 600px;
}
Although it is coded as Tara Tara, what I am doing is simple, I try to display tweets with a time close to the time at each point in the location history and the tweet time. Specifically, since the coordinates remained finely about every 3 minutes, the Tweet tweeted within the time with the location history and the next time (about 3 minutes later) is displayed.
In addition, the trajectory is also displayed using a Google Map method called polyline so that you can see the trajectory you moved.
(1) Location information, Tweet content, and API key information are personal information, so never disclose them!
(2) When executing in a local environment, an error will occur when accessing a local file with Ajax with chrome. Run Chorme with sudo! [* Other *] Access local files with Ajax in Chrome
③ You can only go back to the date when you can get the location history and Tweet data! (Of course)
It may be a reference or almost a copy. .. .. .. Excuse me. .. .. Thank you very much. (I referred to various sites, so please let me know if you say, "Oh, this code is a copy of the one I wrote?")
・ Use Google Timeline to record trips and outings
・ [Capture on the 10th day] Convert created_at of Twitter API to UNIX time and save it in DATETIME
・ Play with twitter API # 3 (Get search results)
-Displaying polylines Google Maps API V3 How to use JavaScript
Since it is a type that I am satisfied with making, there may be some omissions in the explanation, but if it is difficult to understand, please ask. .. ..
Recommended Posts