#------------------
'''
This program creates a calendar.
1. Define the top-left corner
2. Size of rectangle to display the days
3. Run this script
A kml file will be created which can be zipped to create kmz.
'''
import calendar
# Read the header
# It contains the header (xml tag, styles etc.)
with open('header.txt', 'r') as h:
= h.read()
header
# Read the tag-content for displaying days
with open('day_num.txt', 'r') as h:
= h.read()
day_num
# Rectangle containing the days (polygon tab)
with open('day_box.txt', 'r') as h:
= h.read()
day_box
# Read the tag to display month
with open('month_name.txt', 'r') as h:
= h.read()
month_name
# Start the folder tag which contains all the tags under each month
with open('folder_st.txt', 'r') as h:
= h.read()
fst
# End tag for folder/ then document/ then kml
=' </Folder>'
month_end= '''
footer </Folder>
</Document>
</kml>
'''
# Calendar starts with Sunday it can be changed
= calendar.TextCalendar(calendar.SUNDAY)
c
= ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
months
# Top left corner of the calendar (Example: Australia)
= 130.0
cxx = -20.0
cyy # display the calendar
# Create KML file to write
= open('cal.kml', 'w')
f
f.write(header)
# Size of the rectangle
= 0.2
cs for mi in range(12):
# To create 4-months in each column
= cxx + cs * 16 * (mi //4)
cx = cyy - cs * 13 * (mi % 4)
cy = 0
j # Write the name of month
= months[mi]
mname = fst.replace('month_name', mname)
fst_m
f.write(fst_m)
# Write the name of days at top of each month
= ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
days = month_name.replace('month_name', mname)
m_label = m_label.replace('pcoord', f'{cx - 2.0 * cs}, {cy}')
m_label
f.write(m_label)for i in range(7):
= month_name.replace('month_name', days[i])
day_label = day_label.replace('pcoord', f'{cx + i * cs * 2 }, {cy + cs*2}')
day_label = day_label.replace('pushpin_month', 'pushpin_day')
day_label
f.write(day_label)# Create a calendar for each month
for i in c.itermonthdays(2024, mi + 1):
= (j % 7 ) *cs * 2
dx = (j // 7)*cs*2
dy if i>0:
# Coordinates of the rectangle
= day_box.replace('polycoord', f'{cx + dx - cs},{cy - dy -cs},0 {cx + dx-cs},{cy -dy +cs},0 {cx + dx+cs},{cy -dy +cs},0 {cx + dx+cs},{cy -dy -cs},0 {cx + dx-cs},{cy -dy -cs},0')
dbnew
f.write(dbnew)# Color of the days
if j%7 == 6:
= day_num.replace('styleName', 's_ylw-pushpin_weekend')
dnnew else:
= day_num.replace('styleName', 's_ylw-pushpin_weekday')
dnnew = dnnew.replace('daynum', f'{i}')
dnnew = dnnew.replace('pcoord', f'{cx+dx},{cy-dy}')
dnnew
f.write(dnnew)+= 1
j
f.write(month_end)
f.write(footer)
f.close()print('finished')
Background
Today I present you a Calendar which you can display on the GoogleEarth. Do the following and display the calendar.
- Download this file: link to zip file
- Unzip it
- Double click any kmz-file inside
Calendar appears above the globe. On the left, you can find the folders named by month. By double-clicking that folder, you can zoom to that month. That’s it.
If you want to see how it was done, then follow the next sections. The python code and related files are also available inside code folder.
1 Programming in python to create the kml file
1.1 Structure of kml and kmz file
kml file is a xml file with user defined tags. A portion of the file is shown below.
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>New Year Calendar - 2024</name>
<open>1</open>
<StyleMap id="m_ylw-pushpin">
<Pair>
<key>normal</key>
<styleUrl>#s_ylw-pushpin0</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#s_ylw-pushpin_hl00</styleUrl>
</Pair>
</StyleMap>
<StyleMap id="m_ylw-pushpin1">
<Pair>
<key>normal</key>
<styleUrl>#s_ylw-pushpin</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#s_ylw-pushpin_hl</styleUrl>
</Pair>
</StyleMap>
<StyleMap id="m_ylw-pushpin0">
<Pair>
<key>normal</key>
<styleUrl>#s_ylw-pushpin1</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#s_ylw-pushpin_hl0</styleUrl>
</Pair>
</StyleMap>
A simple kml file may contain multiple folders, polygons, paths(lines) and places (point). The file also contains different styles for these shapes.
1.2 Coding
I have divided the kml file into followings:
- Header (Top of the kml which is constant)
- Name of month with surrounding tags (name of month is variable)
- Name of day of week with surrounding tags
- Calendar is produced by using Calendar module which needs year and month as parameter.
- Days are displayed by number and a rectangle. The coordinates can be calculated by using the central coordinates.
The code is self explanatory and presented below. By varying the following parameters, the calendar can be customized.
- Corner-coordinates
- Size of rectangles