Monday, March 20, 2023

How to find Sentinel-2 satellite image for your study area using GoogleEarthEngine

Unlike the Landsat satellite, Sentinel-2 satellite doesn't use Path/Row naming convention to define its scenes instead it uses granules or tiles of 110km x 110km ortho-images in UTM/WGS84 projection.

The tiles are numbered from 1 to 60 followed by three letters, so an example of a valid Sentinel-2 tile number are: 01CCV, 01CDH, 01CDJ, etc.

Now the problem is how do you know the number that covers your study area! Well there are several ways of solving this, one is by visualizing the granules or tiles KML file in you favorite tool.

If you work solely in Google Earth Engine, then I would be a bad idea to load that KML file due to its size. So, an approach to use is to load/import image collection and filter based on region of interest or other criteria and print the 'id' using the id() function as demonstrated in the code snippet below:-

var dataset = ee.ImageCollection('COPERNICUS/S2')
  .filterDate('2022-01-01', '2022-12-31')
  .first();
  

print(dataset.id())

This will print the ID on the console as seen below:-


According to the documentation, 'the first numeric part represents the sensing date and time, the second numeric part represents the product generation date and time, and the final 6-character string is a unique granule identifier indicating its UTM grid reference'.

If you want to get more specific, you could a .filterBounds(...) function to your region of interest. Here I added filterBounds to a location in Abuja, Nigeria.


Note that the image collection will return 'Null' if there is no image available for your filter criteria.

That is it!

Tuesday, February 7, 2023

Using Python Interpret Landsat File Naming Convention

 If you have ever worked with Landsat images, you would have noticed that the image files usually have a long name made-up of letters and numbers that probably looks like this: LC08_L2SP_188054_20221120_20221129_02_T1.

In this article, we will use python to extract the meaning of the file name.

After downloading a Landsat file from the USGS Earth Explorer, there’s surprisingly a lot of information you can get from just the file name. The following web pages provide detailed information on the file naming convention:-

  • https://www.usgs.gov/faqs/what-naming-convention-landsat-collections-level-1-scenes
  • https://gisgeography.com/landsat-file-naming-convention/


The Landsat satellite series is a long-running satellite program that provides high-resolution imagery of the Earth's surface. The images taken by the Landsat satellites are named using a standardized naming convention that includes information about the satellite, the path and row of the image, the date the image was taken, and the band of the image.

Here is an example of a Landsat image file name: LC08_L1TP_012030_20170604_20170615_01_T1

This file name can be interpreted as follows:

LC08: The satellite that took the image (Landsat 8)

L1TP: The processing level of the image (Level 1 Terrain Corrected)

012030: The path and row of the image (path 01, row 20)

20170604: The date the image was taken (June 4, 2017)

20170615: The date the image was processed (June 15, 2017)

01: The band of the image (band 1)

T1: The product type of the image (Type 1)

You can use Python to parse and interpret Landsat image file names by splitting the file name string using the split() method and extracting the relevant pieces of information using string slicing and indexing. For example:

filename = 'LC08_L1TP_012030_20170604_20170615_01_T1'

satellite = filename[:4]  # 'LC8'
processing_level = filename[5:9]  # 'L1TP'
path_row = filename[10:16]  # '012030'
date_taken = filename[17:25]  # '20170604'
date_processed = filename[26:34]  # '20170615'
band = filename[35:37]  # '01'
product_type = filename[38:]  # 'T1'


print(f'''
      The satellite name is: {satellite}, 
      The processing level of the image is: {processing_level}, 
      The path and row of the image is: {path_row}, 
      The date the image was taken on: {date_taken}, 
      The date the image was processed is: {date_processed}, 
      The band of the image is: {band}, 
      The product type of the image is: {product_type}
      ''')


The code use string slicing to get the required information from the file names.

Saturday, February 4, 2023

SVG remove polygon using JS

 In this post, you will find a code snippet that will remove a state polygon on mouse click. The tech stack used are: HTML, CSS, JS and SVG.

The result will look like below image.




First step is to setup a basic HTML page and use the 'object' tag to embed the SVG file into the HTML body like this:-

<object id="svg-object" data="svg_map_filename.svg" type="image/svg+xml"></object>


Then we will update the SVG file with CSS and JS code as follow. In the '.svg' document, we need to put the styles declaration inside cdata, as follows;-

<style type="text/css" media="screen"> <![CDATA[

/*Add CSS code here...*/

  ]]> </style>

The CSS style is added at the top of the svg file just after the opening <svg ...> tag.


Lastly we will add JS code at the end of the  svg file just after the closing <svg ...> tag. The script code must be wrapped inside cdata, as follows;-

<script> <![CDATA[

    // Add JS code here...

  ]]> </script>


Wrapping the CSS or JS codes in the cdata is important so that characters like > don't conflict with XML parsers. Using cdata is highly recommended for embedding style or script in SVG, even if the conflicting character is not given in the style sheet or script file.


That is it!


Monday, January 30, 2023

Python workout in JavaScript

 In this post, I will convert some python code from the book "Python Workout by Reuven M. Lerner" into JavaScript (you may get a copy of the book from his website). The code used in the book are publicly available on his github page.


Lets get started...


Task 1: Generate a random integer from 1 to 100.

Ask the user repeatedly to guess the number. Until they guess correctly, tell them to guess higher or lower.


<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Random Number Generator | Guess the number...</title>

<!-- ***************** CSS ********************* -->
	<style type="text/css">
		body{
			background-color: #db20d96e;
		}

		h2, #num, #submit, #result {
			font-size: 2em;
		}

		h1{
			margin: 0;
			color: #f94711;
		}
	</style>

</head>
<body>



<!-- ***************** HTML ********************* -->
<center>
	<h2>Am thinking of a number, what is it?</h2>

	<input type="number" name="num" id="num" />
	<button id="submit">Submit</button>
	<br>
	<br>

	<label type="text" name="result" id="result" />
</center>



<!-- ***************** JS ********************* -->
<script>

// Funtion to get random number between two nums...
	function getRandomIntInclusive(min, max) {
		  min = Math.ceil(min);
		  max = Math.floor(max);
		  return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
		}
// Guessed number is...
	let guessed_num = getRandomIntInclusive(1, 100);


// Get form entry and compare to the user's guessed number....
	let btn = document.getElementById('submit');

	btn.onclick = (e) => {
		let guess_num = document.getElementById('num').value;
		let result = document.getElementById('result');

		console.log(guess_num);

		if (guessed_num == guess_num){
			// console.log('Correct Guess...');
			result.innerHTML = `Correct Guess... The number in my mind was: <h1>${guessed_num}</h1>`

		} else if (guessed_num < guess_num) {
			// console.log(`Guessed number is too HIGH; try again...`);
			result.innerHTML = `Guessed number is too HIGH; try again...`

		} else if (guessed_num > guess_num) {
			// console.log(`Guessed number is too LOW; try again...`);
			result.innerHTML = `Guessed number is too LOW; try again...`
		}

	}
	
// `${guessed_num}`
</script>

</body>
</html>


Task 2: Summing numbers

Define "mySum". Accepts any number of numeric arguments as inputs. Returns the sum of those numbers. If invoked without any arguments, returns 0.

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Summing Numbers in an array....</title>


<!-- ***************** CSS ********************* -->
	<style type="text/css">
		body{
			margin: 50px;
			background-color: burlywood;
		}

		center{
			background-color: grey;
			border: solid 10px;
			border-radius: 25px;
		}

		h2, #num, #submit, #result {
			font-size: 2em;
		}

		h1{
			margin: 0;
			color: #f94711;
		}

		#num, #submit{
			border-radius: 25px;
		}		
	</style>


</head>
<body>


<!-- ***************** HTML ********************* -->

<center>
	<h2>Enter your list of numbers like this: <i>1, 2, 3, 4, 5</i></h2>

	<input type="text" name="num" id="num" />
	<button id="submit">Submit</button>
	<br>
	<br>

	<label type="text" name="result" id="result" />
</center>



<!-- ***************** JS ********************* -->

<script type="text/javascript">

// Function to sum array of numbers.... https://www.educative.io/answers/how-to-get-the-sum-of-an-array-in-javascript
	function mySum(myarray) {
		  let sum = 0;

		  for (let i = 0; i < myarray.length; i += 1) {
		    sum += (myarray[i] * 1); // multiply by 1 to convert to number: https://www.freecodecamp.org/news/how-to-convert-a-string-to-a-number-in-javascript/
		  }
		  
		  return sum;
		}

// Get form entries....
	let btn = document.getElementById('submit');
	let result = document.getElementById('result');

// Perform the magic...
	btn.onclick = (e) => {
		let list_of_num = document.getElementById('num').value;
		// console.log(typeof(list_of_num))

		// Replace spaces....
		list_of_num = list_of_num.replace(/\s+/g, '');

		// Split by ','...
		list_of_num = list_of_num.split(',');

		// Use the function above to sum the list...
		let sum_of_list_of_num = mySum(list_of_num)

		// Display result...
		if (isNaN(sum_of_list_of_num)){
			result.innerHTML = `<h1>Invalid</h1> Your entries most all be numbers.`;
		} else {
			result.innerHTML = `The Sum of ${list_of_num} is: <h1>${sum_of_list_of_num}</h1>`;
		}
		


		// console.log(`${list_of_num}`)
		// console.log(mySum(sum_of_list_of_num))
	}


</script>


</body>
</html>



Task 3: Running Time Average

Here we will use javascript to dynamically add the run time input box.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Running Time Average...</title>

<!-- ------------------------ CSS -------------------------------- -->
  <style type="text/css">
    #num{
          height: 50px;
          width: 320px;
          font-size: xx-large;
        }

    #submit, #addmore{
      font-size: x-large;
      height: 70px;
    }

    #result{
      color: green;
      font-size: xxx-large;
    }


  </style>

</head>
<body>


<!-- ------------------------ HMTL -------------------------------- -->

<center>
  <h1>Enter the time run for the 10km: </h1>

  <input type="number" name="num" id="num" class="num" />
  <button id="submit">Submit</button>
  <button id="addmore">Add More Time</button>

  <br>
  <br>

  <label type="text" name="result" id="result" />
</center>



<!-- ------------------------ JS -------------------------------- -->


<script type="text/javascript">


  // Select the button element
  const submitButton = document.querySelector('#submit');
  const addmoreButton = document.querySelector('#addmore');

  const result = document.getElementById('result');



  // Add a click event listener to the addmore button
  addmoreButton.addEventListener('click', function() {
    // Create a new element
    const elem0 = document.createElement('center');
    const elem1 = document.createElement('input');
    const elem2 = document.createElement('br');


    // Set the element's content and style
    elem1.style.color = 'red';
    elem1.style.width = '600px';
    elem1.style.height = '50px';
    elem1.style.fontSize = 'xx-large';

    elem1.type = 'number';

    // Add a class and id named 'num' to the element
    elem1.className = 'num';
    elem1.id = 'num';


    // Append the 'input' to the 'center' element
    elem0.appendChild(elem1);

    // Append the element to the DOM
    document.body.appendChild(elem0);

    // document.body.appendChild(elem1);
    document.body.appendChild(elem2);

  });




// ---------------------------------------------

 // Add a click event listener to the submit button
  submitButton.addEventListener('click', function() {


    // const all_time = document.getElementsByClassName('num');
    const all_time = document.querySelectorAll('.num');


    const averageTimeRan = Array.from(all_time).reduce((total, elem) => total + parseFloat(elem.value), 0) / all_time.length;

    result.innerHTML = `The average of total time ran is: ${averageTimeRan.toFixed(2)}`;

  });



</script>


</body>
</html>

Wednesday, January 25, 2023

Wrangling the 'Database of health facilities in Nigeria' using QGIS and Python

 A database of health facilities in Nigeria would be a valuable resource for both healthcare providers and the general public. It could provide information about the types of facilities available, their locations, and the services they offer. This information could help healthcare providers refer patients to appropriate facilities, and it could help the public find the nearest and most suitable facilities for their needs.

There are many different types of health facilities in Nigeria, including hospitals, clinics, and pharmacies. Some facilities may specialize in a particular area of healthcare, such as maternal and child health, while others may offer a range of general medical services. The availability and accessibility of these facilities can vary greatly depending on where you are in the country.

Having a comprehensive database of health facilities in Nigeria would allow for better planning and resource allocation by the government and healthcare organizations. It could also help to ensure that underserved areas are not overlooked and that there is an adequate distribution of healthcare resources throughout the country.

In addition to providing information about health facilities, such a database could also include information about the availability of healthcare professionals, including doctors, nurses, and other medical staff. This could be particularly useful for rural areas where access to healthcare professionals may be limited.

Overall, a database of health facilities in Nigeria would be a valuable tool for improving the country's healthcare system and ensuring that all citizens have access to the healthcare services they need.










Wednesday, January 18, 2023

Python for GIS data wrangling

 Python is a powerful and widely used programming language that is well-suited for GIS data wrangling tasks. There are a number of libraries and tools available in Python that can be used to perform a wide range of GIS data wrangling tasks, including reading and writing various geospatial data formats, performing spatial transformations and projections, and performing spatial analyses and visualizations.

Some of the most commonly used libraries for GIS data wrangling in Python include:

pandas: A powerful data manipulation and analysis library that is widely used for GIS data wrangling. It provides a range of functions for reading and writing geospatial data formats, including CSV, shapefile, KML, and GeoJSON.

geopandas: A library built on top of pandas that provides additional functionality for working with geospatial data. It allows you to manipulate and visualize geospatial data using familiar pandas dataframes, and includes support for geographic projections and spatial operations.

fiona: A library for reading and writing geospatial data formats, including shapefiles, GeoJSON, and KML. It can be used in combination with other libraries, such as geopandas, to perform advanced GIS data wrangling tasks.

shapely: A library for working with geometric objects such as points, lines, and polygons. It provides functions for creating, manipulating, and performing spatial operations on these objects, and can be used to clean and transform geospatial data.

Other useful libraries for GIS data wrangling in Python include rasterio, gdal, and pyproj, among others. These libraries can be used to perform a wide range of GIS data wrangling tasks, including reading and writing various geospatial data formats, performing spatial transformations and projections, and performing spatial analyses and visualizations.

Over the past few years, I have used python to wrangle different kinds of GIS data and some example can be reviewed below:-

1- Python GIS data wrangling - Harris County Appraisal District

2- GIS data wrangling with python - Gridded Street Finder

3- Geocoding and Reverse Geocoding with Python

4- Python GIS data wrangling - Mapping supper eagles head coaches since 1949

5- Python GIS Data Wrangling - U.S. Drought Monitor

6- Python Programming for GIS Data Processing in QGIS

7- GIS data wrangling with python - case study of 'African Journals Online' featured countries


If you need help with wrangling your GIS data, you may contact me via email/phone details on my website:  UmarYusuf.com

Cheers!

Tuesday, January 3, 2023

Using chatGPT (Generative Pretrained Transformer) to map first 100 regions to welcome the new year

 ChatGPT is a variant of the GPT (Generative Pretrained Transformer) language model that is specifically designed for generating human-like text in a conversational context. It is not a tool for creating maps or visual representations of data.

How do we now use it to make maps?

The answer is simple, we will use ChatGPT to generate text that lists the first 100 regions to welcome the new year by providing the model with a prompt in the form of a natural language question or statement, such as "Can you provide a list of the first 100 regions to welcome the new year?", and then allowing the model to generate the text.


We can also ask ChatGPT to geocode the places for us and that will return the geographic coordinates as seen below;-



Now, we got all we needed to map the first 100 regions to welcome the new year. Copy the chatGPT text into your GIS software of choice for the mapping, of course the text will be formatted appropriately as required be the GIS software you want to use.

As for me I use QGIS software and here is how it looks:-


The New Year is celebrated on January 1st in most countries around the world. However, different countries have different time zones, so the New Year is actually celebrated at different times in different parts of the world.

The new year is celebrated at different times around the world. celebrate the new year is typically Samoa and Christmas Island in Kiribati, which are the first to enter the new year due to their location west of the International Date Line. The last place to celebrate the new year is usually Baker Island and Howland Island, which are the last to enter the new year due to their location east of the International Date Line. However, these locations are uninhabited, so the last place where the new year is celebrated with a significant population is usually American Samoa.


Thank you for following.

Wednesday, December 28, 2022

Python GIS data wrangling - Harris County Appraisal District

 The task at hand is to prepare a spreadsheet file with links to "Appraisal District Maps in Harris County, Texas".


There twenty two (22) appraisal districts as seen on the facet-maps page above. So, now we need to links to the detailed map in PDF format.

For example, if you open the Houston facet map, you see several facet numbers that leads to the detail maps.

https://public.hcad.org/maps/Houston.asp


If you click on any of the numbers (example 5156A), it should take you to a page that looks like the one below where you will see that the map is subdivided into 12 detailed maps in PDF format.

https://public.hcad.org/cgi-bin/IMap.asp?map=5156A


Now it is the links to the detailed maps in PDF that we need to collect into spreadsheet table.

https://public.hcad.org/iMaps/Tiles/Color/5156A1.pdf


Scrapping the links was not easy as the website is had anti-scrape mechanisms implemented on it. So, we can manually collect the HTML source tags that contain what we wanted then use python scripting to wrangle it into the format we wanted.

For example for each district, the facet numbers are embedded in a '<map>...</map>' tag as seen below.

iMap = ''' <map name="ISDMap">
            <area shape="rect" coords="487, 59 , 525, 86" href="/cgi-bin/IMap.asp?map=5262A" alt="">
            <area shape="rect" coords="525, 59 , 564, 86" href="/cgi-bin/IMap.asp?map=5262B" alt="">
            <area shape="rect" coords="564, 59 , 604, 85" href="/cgi-bin/IMap.asp?map=5362A" alt="">
            <area shape="rect" coords="603, 59 , 643, 86" href="/cgi-bin/IMap.asp?map=5362B" alt="">
            <area shape="rect" coords="643, 59 , 682, 85" href="/cgi-bin/IMap.asp?map=5462A" alt="">
            <area shape="rect" coords="682, 59 , 722, 86" href="/cgi-bin/IMap.asp?map=5462B" alt="">
            <area shape="rect" coords="487, 86 , 525,111" href="/cgi-bin/IMap.asp?map=5262C" alt="">
            <area shape="rect" coords="524, 85 , 565,110" href="/cgi-bin/IMap.asp?map=5262D" alt="">
            <area shape="rect" coords="564, 85 , 604,111" href="/cgi-bin/IMap.asp?map=5362C" alt="">
            <area shape="rect" coords="603, 85 , 643,111" href="/cgi-bin/IMap.asp?map=5362D" alt="">
            <area shape="rect" coords="643, 85 , 682,110" href="/cgi-bin/IMap.asp?map=5462C" alt="">
            <area shape="rect" coords="681, 85 , 722,111" href="/cgi-bin/IMap.asp?map=5462D" alt="">
            <area shape="rect" coords="486,110 , 525,137" href="/cgi-bin/IMap.asp?map=5261A" alt="">
            <area shape="rect" coords="525,110 , 565,137" href="/cgi-bin/IMap.asp?map=5261B" alt="">
            <area shape="rect" coords="564,110 , 604,137" href="/cgi-bin/IMap.asp?map=5361A" alt="">
            <area shape="rect" coords="603,110 , 643,137" href="/cgi-bin/IMap.asp?map=5261B" alt="">
            <area shape="rect" coords="643,110 , 682,137" href="/cgi-bin/IMap.asp?map=5461A" alt="">
            <area shape="rect" coords="681,110 , 722,137" href="/cgi-bin/IMap.asp?map=5461B" alt="">
            <area shape="rect" coords="368,137 , 409,163" href="/cgi-bin/IMap.asp?map=5061D" alt="">
            <area shape="rect" coords="408,137 , 447,163" href="/cgi-bin/IMap.asp?map=5161C" alt="">
            <area shape="rect" coords="446,136 , 487,162" href="/cgi-bin/IMap.asp?map=5161D" alt="">
            <area shape="rect" coords="486,137 , 525,163" href="/cgi-bin/IMap.asp?map=5261C" alt="">
            <area shape="rect" coords="524,137 , 565,163" href="/cgi-bin/IMap.asp?map=5261D" alt="">
            <area shape="rect" coords="564,137 , 604,162" href="/cgi-bin/IMap.asp?map=5361C" alt="">
            <area shape="rect" coords="603,137 , 643,163" href="/cgi-bin/IMap.asp?map=5361D" alt="">
            <area shape="rect" coords="642,137 , 682,163" href="/cgi-bin/IMap.asp?map=5461C" alt="">
            <area shape="rect" coords="682,136 , 722,162" href="/cgi-bin/IMap.asp?map=5461D" alt="">
            <area shape="rect" coords="721,137 , 761,163" href="/cgi-bin/IMap.asp?map=5561C" alt="">
            <area shape="rect" coords="760,137 , 800,163" href="/cgi-bin/IMap.asp?map=5561D" alt="">
            <area shape="rect" coords="368,163 , 408,188" href="/cgi-bin/IMap.asp?map=5060B" alt="">
            <area shape="rect" coords="407,163 , 447,188" href="/cgi-bin/IMap.asp?map=5160A" alt="">
            <area shape="rect" coords="446,162 , 487,189" href="/cgi-bin/IMap.asp?map=5160B" alt="">
            <area shape="rect" coords="486,163 , 525,188" href="/cgi-bin/IMap.asp?map=5260A" alt="">
            <area shape="rect" coords="525,163 , 565,189" href="/cgi-bin/IMap.asp?map=5260B" alt="">
            <area shape="rect" coords="564,162 , 604,188" href="/cgi-bin/IMap.asp?map=5360A" alt="">
            <area shape="rect" coords="603,163 , 644,189" href="/cgi-bin/IMap.asp?map=5360B" alt="">
            <area shape="rect" coords="642,163 , 682,189" href="/cgi-bin/IMap.asp?map=5460A" alt="">
            <area shape="rect" coords="682,163 , 722,189" href="/cgi-bin/IMap.asp?map=5460B" alt="">
            <area shape="rect" coords="721,162 , 760,188" href="/cgi-bin/IMap.asp?map=5560A" alt="">
            <area shape="rect" coords="760,163 , 800,189" href="/cgi-bin/IMap.asp?map=5560B" alt="">
            <area shape="rect" coords="368,189 , 408,214" href="/cgi-bin/IMap.asp?map=5060D" alt="">
            <area shape="rect" coords="407,189 , 447,214" href="/cgi-bin/IMap.asp?map=5160C" alt="">
            <area shape="rect" coords="446,188 , 487,214" href="/cgi-bin/IMap.asp?map=5160D" alt="">
            <area shape="rect" coords="486,189 , 525,214" href="/cgi-bin/IMap.asp?map=5260C" alt="">
            <area shape="rect" coords="524,189 , 565,214" href="/cgi-bin/IMap.asp?map=5260D" alt="">
            <area shape="rect" coords="564,189 , 604,214" href="/cgi-bin/IMap.asp?map=5360C" alt="">
            <area shape="rect" coords="603,189 , 643,214" href="/cgi-bin/IMap.asp?map=5360D" alt="">
            <area shape="rect" coords="642,189 , 682,214" href="/cgi-bin/IMap.asp?map=5460C" alt="">
            <area shape="rect" coords="681,189 , 722,214" href="/cgi-bin/IMap.asp?map=5460D" alt="">
            <area shape="rect" coords="721,189 , 761,214" href="/cgi-bin/IMap.asp?map=5560C" alt="">
            <area shape="rect" coords="761,188 , 800,214" href="/cgi-bin/IMap.asp?map=5560D" alt="">
            <area shape="rect" coords="838,189 , 879,214" href="/cgi-bin/IMap.asp?map=5660D" alt="">
            <area shape="rect" coords="877,189 , 917,214" href="/cgi-bin/IMap.asp?map=5760C" alt="">
            <area shape="rect" coords="408,214 , 447,240" href="/cgi-bin/IMap.asp?map=5159A" alt="">
            <area shape="rect" coords="446,214 , 487,240" href="/cgi-bin/IMap.asp?map=5159B" alt="">
            <area shape="rect" coords="486,214 , 525,240" href="/cgi-bin/IMap.asp?map=5259A" alt="">
            <area shape="rect" coords="524,214 , 565,240" href="/cgi-bin/IMap.asp?map=5259B" alt="">
            <area shape="rect" coords="565,214 , 604,240" href="/cgi-bin/IMap.asp?map=5359A" alt="">
            <area shape="rect" coords="604,214 , 643,239" href="/cgi-bin/IMap.asp?map=5359B" alt="">
            <area shape="rect" coords="643,213 , 682,240" href="/cgi-bin/IMap.asp?map=5459A" alt="">
            <area shape="rect" coords="682,214 , 722,240" href="/cgi-bin/IMap.asp?map=5459B" alt="">
            <area shape="rect" coords="722,214 , 761,240" href="/cgi-bin/IMap.asp?map=5559A" alt="">
            <area shape="rect" coords="761,214 , 800,240" href="/cgi-bin/IMap.asp?map=5559B" alt="">
            <area shape="rect" coords="800,214 , 839,240" href="/cgi-bin/IMap.asp?map=5659A" alt="">
            <area shape="rect" coords="839,214 , 878,240" href="/cgi-bin/IMap.asp?map=5659B" alt="">
            <area shape="rect" coords="878,214 , 917,240" href="/cgi-bin/IMap.asp?map=5759A" alt="">
            <area shape="rect" coords="917,213 , 957,240" href="/cgi-bin/IMap.asp?map=5759B" alt="">
            <area shape="rect" coords="447,240 , 487,266" href="/cgi-bin/IMap.asp?map=5159D" alt="">
            <area shape="rect" coords="487,240 , 525,266" href="/cgi-bin/IMap.asp?map=5259C" alt="">
            <area shape="rect" coords="525,239 , 565,266" href="/cgi-bin/IMap.asp?map=5259D" alt="">
            <area shape="rect" coords="565,240 , 604,266" href="/cgi-bin/IMap.asp?map=5359C" alt="">
            <area shape="rect" coords="604,239 , 643,266" href="/cgi-bin/IMap.asp?map=5359D" alt="">
            <area shape="rect" coords="643,240 , 682,266" href="/cgi-bin/IMap.asp?map=5459C" alt="">
            <area shape="rect" coords="682,240 , 722,266" href="/cgi-bin/IMap.asp?map=5459D" alt="">
            <area shape="rect" coords="721,240 , 761,266" href="/cgi-bin/IMap.asp?map=5559C" alt="">
            <area shape="rect" coords="760,240 , 800,265" href="/cgi-bin/IMap.asp?map=5559D" alt="">
            <area shape="rect" coords="800,240 , 839,266" href="/cgi-bin/IMap.asp?map=5659C" alt="">
            <area shape="rect" coords="840,240 , 879,266" href="/cgi-bin/IMap.asp?map=5659D" alt="">
            <area shape="rect" coords="878,240 , 917,266" href="/cgi-bin/IMap.asp?map=5759C" alt="">
            <area shape="rect" coords="917,240 , 957,266" href="/cgi-bin/IMap.asp?map=5759D" alt="">
            <area shape="rect" coords="448,266 , 487,292" href="/cgi-bin/IMap.asp?map=5158B" alt="">
            <area shape="rect" coords="487,266 , 525,292" href="/cgi-bin/IMap.asp?map=5258A" alt="">
            <area shape="rect" coords="525,265 , 565,292" href="/cgi-bin/IMap.asp?map=5258B" alt="">
            <area shape="rect" coords="565,266 , 604,292" href="/cgi-bin/IMap.asp?map=5358A" alt="">
            <area shape="rect" coords="604,266 , 643,292" href="/cgi-bin/IMap.asp?map=5358B" alt="">
            <area shape="rect" coords="643,266 , 682,292" href="/cgi-bin/IMap.asp?map=5458A" alt="">
            <area shape="rect" coords="682,265 , 722,292" href="/cgi-bin/IMap.asp?map=5458B" alt="">
            <area shape="rect" coords="722,266 , 761,292" href="/cgi-bin/IMap.asp?map=5558A" alt="">
            <area shape="rect" coords="761,266 , 800,292" href="/cgi-bin/IMap.asp?map=5558B" alt="">
            <area shape="rect" coords="800,266 , 839,292" href="/cgi-bin/IMap.asp?map=5658A" alt="">
            <area shape="rect" coords="839,266 , 878,292" href="/cgi-bin/IMap.asp?map=5658B" alt="">
            <area shape="rect" coords="877,266 , 917,292" href="/cgi-bin/IMap.asp?map=5758A" alt="">
            <area shape="rect" coords="916,265 , 957,292" href="/cgi-bin/IMap.asp?map=5758B" alt="">
            <area shape="rect" coords="957,266 , 996,292" href="/cgi-bin/IMap.asp?map=5858A" alt="">
            <area shape="rect" coords="408,291 , 447,317" href="/cgi-bin/IMap.asp?map=5158C" alt="">
            <area shape="rect" coords="447,292 , 487,317" href="/cgi-bin/IMap.asp?map=5158D" alt="">
            <area shape="rect" coords="487,292 , 525,317" href="/cgi-bin/IMap.asp?map=5258C" alt="">
            <area shape="rect" coords="525,292 , 565,317" href="/cgi-bin/IMap.asp?map=5258D" alt="">
            <area shape="rect" coords="565,292 , 604,317" href="/cgi-bin/IMap.asp?map=5358C" alt="">
            <area shape="rect" coords="604,292 , 643,317" href="/cgi-bin/IMap.asp?map=5358D" alt="">
            <area shape="rect" coords="643,291 , 682,317" href="/cgi-bin/IMap.asp?map=5458C" alt="">
            <area shape="rect" coords="682,292 , 722,317" href="/cgi-bin/IMap.asp?map=5458D" alt="">
            <area shape="rect" coords="722,292 , 761,317" href="/cgi-bin/IMap.asp?map=5558C" alt="">
            <area shape="rect" coords="761,292 , 800,317" href="/cgi-bin/IMap.asp?map=5558D" alt="">
            <area shape="rect" coords="800,292 , 839,317" href="/cgi-bin/IMap.asp?map=5658C" alt="">
            <area shape="rect" coords="839,292 , 878,317" href="/cgi-bin/IMap.asp?map=5658D" alt="">
            <area shape="rect" coords="878,292 , 917,317" href="/cgi-bin/IMap.asp?map=5758C" alt="">
            <area shape="rect" coords="917,292 , 957,317" href="/cgi-bin/IMap.asp?map=5758D" alt="">
            <area shape="rect" coords="957,291 , 996,317" href="/cgi-bin/IMap.asp?map=5858C" alt="">
            <area shape="rect" coords=" 94,317 , 133,343" href="/cgi-bin/IMap.asp?map=4757A" alt="">
            <area shape="rect" coords="132,317 , 173,343" href="/cgi-bin/IMap.asp?map=4757B" alt="">
            <area shape="rect" coords="211,317 , 252,343" href="/cgi-bin/IMap.asp?map=4857B" alt="">
            <area shape="rect" coords="250,317 , 290,342" href="/cgi-bin/IMap.asp?map=4957A" alt="">
            <area shape="rect" coords="369,316 , 408,343" href="/cgi-bin/IMap.asp?map=5057B" alt="">
            <area shape="rect" coords="408,317 , 447,343" href="/cgi-bin/IMap.asp?map=5157A" alt="">
            <area shape="rect" coords="447,317 , 487,343" href="/cgi-bin/IMap.asp?map=5157B" alt="">
            <area shape="rect" coords="486,316 , 525,343" href="/cgi-bin/IMap.asp?map=5257A" alt="">
            <area shape="rect" coords="525,317 , 566,343" href="/cgi-bin/IMap.asp?map=5257B" alt="">
            <area shape="rect" coords="565,317 , 605,343" href="/cgi-bin/IMap.asp?map=5357A" alt="">
            <area shape="rect" coords="605,317 , 644,343" href="/cgi-bin/IMap.asp?map=5357B" alt="">
            <area shape="rect" coords="643,316 , 683,343" href="/cgi-bin/IMap.asp?map=5457A" alt="">
            <area shape="rect" coords="683,317 , 723,343" href="/cgi-bin/IMap.asp?map=5457B" alt="">
            <area shape="rect" coords="722,317 , 761,343" href="/cgi-bin/IMap.asp?map=5557A" alt="">
            <area shape="rect" coords="761,317 , 801,343" href="/cgi-bin/IMap.asp?map=5557B" alt="">
            <area shape="rect" coords="801,317 , 839,343" href="/cgi-bin/IMap.asp?map=5657A" alt="">
            <area shape="rect" coords="839,316 , 879,343" href="/cgi-bin/IMap.asp?map=5657B" alt="">
            <area shape="rect" coords="370,343 , 409,369" href="/cgi-bin/IMap.asp?map=5057D" alt="">
            <area shape="rect" coords="408,343 , 448,369" href="/cgi-bin/IMap.asp?map=5157C" alt="">
            <area shape="rect" coords="448,343 , 488,369" href="/cgi-bin/IMap.asp?map=5157D" alt="">
            <area shape="rect" coords="488,343 , 526,369" href="/cgi-bin/IMap.asp?map=5257C" alt="">
            <area shape="rect" coords="526,343 , 566,369" href="/cgi-bin/IMap.asp?map=5257D" alt="">
            <area shape="rect" coords="566,343 , 605,369" href="/cgi-bin/IMap.asp?map=5357C" alt="">
            <area shape="rect" coords="605,342 , 644,368" href="/cgi-bin/IMap.asp?map=5357D" alt="">
            <area shape="rect" coords="644,343 , 683,369" href="/cgi-bin/IMap.asp?map=5457C" alt="">
            <area shape="rect" coords="683,343 , 723,369" href="/cgi-bin/IMap.asp?map=5457D" alt="">
            <area shape="rect" coords="723,343 , 761,369" href="/cgi-bin/IMap.asp?map=5557C" alt="">
            <area shape="rect" coords="761,343 , 801,369" href="/cgi-bin/IMap.asp?map=5557D" alt="">
            <area shape="rect" coords="801,343 , 840,369" href="/cgi-bin/IMap.asp?map=5657C" alt="">
            <area shape="rect" coords="840,342 , 879,369" href="/cgi-bin/IMap.asp?map=5657D" alt="">
            <area shape="rect" coords=" 94,343 , 134,369" href="/cgi-bin/IMap.asp?map=4757C" alt="">
            <area shape="rect" coords="134,342 , 174,369" href="/cgi-bin/IMap.asp?map=4757D" alt="">
            <area shape="rect" coords="173,343 , 213,369" href="/cgi-bin/IMap.asp?map=4857C" alt="">
            <area shape="rect" coords="211,343 , 251,368" href="/cgi-bin/IMap.asp?map=4857D" alt="">
            <area shape="rect" coords="251,343 , 291,369" href="/cgi-bin/IMap.asp?map=4957C" alt="">
            <area shape="rect" coords="291,342 , 330,369" href="/cgi-bin/IMap.asp?map=4957D" alt="">
            <area shape="rect" coords=" 94,368 , 134,394" href="/cgi-bin/IMap.asp?map=4756A" alt="">
            <area shape="rect" coords="134,369 , 173,394" href="/cgi-bin/IMap.asp?map=4756B" alt="">
            <area shape="rect" coords="172,368 , 212,394" href="/cgi-bin/IMap.asp?map=4856A" alt="">
            <area shape="rect" coords="212,369 , 252,394" href="/cgi-bin/IMap.asp?map=4856B" alt="">
            <area shape="rect" coords="251,368 , 291,394" href="/cgi-bin/IMap.asp?map=4956A" alt="">
            <area shape="rect" coords="290,368 , 330,394" href="/cgi-bin/IMap.asp?map=4956B" alt="">
            <area shape="rect" coords="329,369 , 369,394" href="/cgi-bin/IMap.asp?map=5056A" alt="">
            <area shape="rect" coords="370,368 , 409,394" href="/cgi-bin/IMap.asp?map=5056B" alt="">
            <area shape="rect" coords="409,369 , 448,394" href="/cgi-bin/IMap.asp?map=5156A" alt="">
            <area shape="rect" coords="447,369 , 488,394" href="/cgi-bin/IMap.asp?map=5156B" alt="">
            <area shape="rect" coords="487,369 , 526,394" href="/cgi-bin/IMap.asp?map=5256A" alt="">
            <area shape="rect" coords="526,369 , 566,394" href="/cgi-bin/IMap.asp?map=5256B" alt="">
            <area shape="rect" coords="566,369 , 605,394" href="/cgi-bin/IMap.asp?map=5356A" alt="">
            <area shape="rect" coords="604,368 , 643,393" href="/cgi-bin/IMap.asp?map=5356B" alt="">
            <area shape="rect" coords="644,369 , 683,394" href="/cgi-bin/IMap.asp?map=5456A" alt="">
            <area shape="rect" coords="683,369 , 723,394" href="/cgi-bin/IMap.asp?map=5456B" alt="">
            <area shape="rect" coords="723,369 , 762,394" href="/cgi-bin/IMap.asp?map=5556A" alt="">
            <area shape="rect" coords="761,369 , 801,394" href="/cgi-bin/IMap.asp?map=5556B" alt="">
            <area shape="rect" coords="801,369 , 840,394" href="/cgi-bin/IMap.asp?map=5656A" alt="">
            <area shape="rect" coords="840,369 , 879,394" href="/cgi-bin/IMap.asp?map=5656B" alt="">
            <area shape="rect" coords=" 95,394 , 134,419" href="/cgi-bin/IMap.asp?map=4756C" alt="">
            <area shape="rect" coords="134,393 , 173,419" href="/cgi-bin/IMap.asp?map=4756D" alt="">
            <area shape="rect" coords="173,393 , 213,419" href="/cgi-bin/IMap.asp?map=4856C" alt="">
            <area shape="rect" coords="212,393 , 252,419" href="/cgi-bin/IMap.asp?map=4856D" alt="">
            <area shape="rect" coords="251,394 , 290,419" href="/cgi-bin/IMap.asp?map=4956C" alt="">
            <area shape="rect" coords="289,393 , 329,419" href="/cgi-bin/IMap.asp?map=4956D" alt="">
            <area shape="rect" coords="330,393 , 370,419" href="/cgi-bin/IMap.asp?map=5056C" alt="">
            <area shape="rect" coords="369,393 , 408,420" href="/cgi-bin/IMap.asp?map=5056D" alt="">
            <area shape="rect" coords="409,394 , 447,420" href="/cgi-bin/IMap.asp?map=5156C" alt="">
            <area shape="rect" coords="448,395 , 487,420" href="/cgi-bin/IMap.asp?map=5156D" alt="">
            <area shape="rect" coords="487,394 , 525,420" href="/cgi-bin/IMap.asp?map=5256C" alt="">
            <area shape="rect" coords="525,394 , 565,420" href="/cgi-bin/IMap.asp?map=5256D" alt="">
            <area shape="rect" coords="565,394 , 604,419" href="/cgi-bin/IMap.asp?map=5356C" alt="">
            <area shape="rect" coords="605,394 , 644,420" href="/cgi-bin/IMap.asp?map=5356D" alt="">
            <area shape="rect" coords="643,394 , 682,420" href="/cgi-bin/IMap.asp?map=5456C" alt="">
            <area shape="rect" coords="682,394 , 723,420" href="/cgi-bin/IMap.asp?map=5456D" alt="">
            <area shape="rect" coords="722,394 , 761,420" href="/cgi-bin/IMap.asp?map=5556C" alt="">
            <area shape="rect" coords="762,394 , 801,420" href="/cgi-bin/IMap.asp?map=5556D" alt="">
            <area shape="rect" coords="801,393 , 839,420" href="/cgi-bin/IMap.asp?map=5656C" alt="">
            <area shape="rect" coords="839,394 , 879,420" href="/cgi-bin/IMap.asp?map=5656D" alt="">
            <area shape="rect" coords="878,393 , 918,419" href="/cgi-bin/IMap.asp?map=5756C" alt="">
            <area shape="rect" coords="291,419 , 330,446" href="/cgi-bin/IMap.asp?map=4955B" alt="">
            <area shape="rect" coords="329,419 , 369,445" href="/cgi-bin/IMap.asp?map=5055A" alt="">
            <area shape="rect" coords="370,420 , 408,445" href="/cgi-bin/IMap.asp?map=5055B" alt="">
            <area shape="rect" coords="408,420 , 447,446" href="/cgi-bin/IMap.asp?map=5155A" alt="">
            <area shape="rect" coords="447,419 , 487,446" href="/cgi-bin/IMap.asp?map=5155B" alt="">
            <area shape="rect" coords="487,420 , 526,446" href="/cgi-bin/IMap.asp?map=5255A" alt="">
            <area shape="rect" coords="526,419 , 566,445" href="/cgi-bin/IMap.asp?map=5255B" alt="">
            <area shape="rect" coords="565,420 , 605,446" href="/cgi-bin/IMap.asp?map=5355A" alt="">
            <area shape="rect" coords="604,419 , 643,446" href="/cgi-bin/IMap.asp?map=5355B" alt="">
            <area shape="rect" coords="644,420 , 683,446" href="/cgi-bin/IMap.asp?map=5455A" alt="">
            <area shape="rect" coords="682,420 , 723,446" href="/cgi-bin/IMap.asp?map=5455B" alt="">
            <area shape="rect" coords="723,419 , 762,445" href="/cgi-bin/IMap.asp?map=5555A" alt="">
            <area shape="rect" coords="761,420 , 801,446" href="/cgi-bin/IMap.asp?map=5555B" alt="">
            <area shape="rect" coords="801,420 , 839,446" href="/cgi-bin/IMap.asp?map=5655A" alt="">
            <area shape="rect" coords="839,420 , 879,446" href="/cgi-bin/IMap.asp?map=5655B" alt="">
            <area shape="rect" coords="879,420 , 918,446" href="/cgi-bin/IMap.asp?map=5755A" alt="">
            <area shape="rect" coords="290,446 , 329,472" href="/cgi-bin/IMap.asp?map=4955D" alt="">
            <area shape="rect" coords="329,445 , 370,472" href="/cgi-bin/IMap.asp?map=5055C" alt="">
            <area shape="rect" coords="369,445 , 409,472" href="/cgi-bin/IMap.asp?map=5055D" alt="">
            <area shape="rect" coords="408,445 , 448,472" href="/cgi-bin/IMap.asp?map=5155C" alt="">
            <area shape="rect" coords="447,446 , 488,472" href="/cgi-bin/IMap.asp?map=5155D" alt="">
            <area shape="rect" coords="487,446 , 526,472" href="/cgi-bin/IMap.asp?map=5255C" alt="">
            <area shape="rect" coords="525,445 , 566,472" href="/cgi-bin/IMap.asp?map=5255D" alt="">
            <area shape="rect" coords="565,446 , 605,472" href="/cgi-bin/IMap.asp?map=5355C" alt="">
            <area shape="rect" coords="605,446 , 644,472" href="/cgi-bin/IMap.asp?map=5355D" alt="">
            <area shape="rect" coords="643,445 , 683,471" href="/cgi-bin/IMap.asp?map=5455C" alt="">
            <area shape="rect" coords="683,446 , 723,472" href="/cgi-bin/IMap.asp?map=5455D" alt="">
            <area shape="rect" coords="723,445 , 762,472" href="/cgi-bin/IMap.asp?map=5555C" alt="">
            <area shape="rect" coords="762,446 , 801,472" href="/cgi-bin/IMap.asp?map=5555D" alt="">
            <area shape="rect" coords="800,446 , 840,472" href="/cgi-bin/IMap.asp?map=5655C" alt="">
            <area shape="rect" coords="840,446 , 878,472" href="/cgi-bin/IMap.asp?map=5655D" alt="">
            <area shape="rect" coords="878,446 , 917,472" href="/cgi-bin/IMap.asp?map=5755C" alt="">
            <area shape="rect" coords="291,472 , 330,497" href="/cgi-bin/IMap.asp?map=4954B" alt="">
            <area shape="rect" coords="329,472 , 370,497" href="/cgi-bin/IMap.asp?map=5054A" alt="">
            <area shape="rect" coords="369,472 , 408,497" href="/cgi-bin/IMap.asp?map=5054B" alt="">
            <area shape="rect" coords="409,472 , 448,497" href="/cgi-bin/IMap.asp?map=5154A" alt="">
            <area shape="rect" coords="448,472 , 488,497" href="/cgi-bin/IMap.asp?map=5154B" alt="">
            <area shape="rect" coords="487,472 , 525,497" href="/cgi-bin/IMap.asp?map=5254A" alt="">
            <area shape="rect" coords="525,472 , 566,497" href="/cgi-bin/IMap.asp?map=5254B" alt="">
            <area shape="rect" coords="566,472 , 605,497" href="/cgi-bin/IMap.asp?map=5354A" alt="">
            <area shape="rect" coords="605,472 , 644,497" href="/cgi-bin/IMap.asp?map=5354B" alt="">
            <area shape="rect" coords="644,472 , 683,497" href="/cgi-bin/IMap.asp?map=5454A" alt="">
            <area shape="rect" coords="682,472 , 723,497" href="/cgi-bin/IMap.asp?map=5454B" alt="">
            <area shape="rect" coords="722,471 , 762,497" href="/cgi-bin/IMap.asp?map=5554A" alt="">
            <area shape="rect" coords="761,472 , 801,497" href="/cgi-bin/IMap.asp?map=5554B" alt="">
            <area shape="rect" coords="800,471 , 840,497" href="/cgi-bin/IMap.asp?map=5654A" alt="">
            <area shape="rect" coords="840,472 , 879,497" href="/cgi-bin/IMap.asp?map=5654B" alt="">
            <area shape="rect" coords="879,472 , 917,497" href="/cgi-bin/IMap.asp?map=5754A" alt="">
            <area shape="rect" coords="290,497 , 330,523" href="/cgi-bin/IMap.asp?map=4954D" alt="">
            <area shape="rect" coords="329,496 , 370,523" href="/cgi-bin/IMap.asp?map=5054C" alt="">
            <area shape="rect" coords="369,497 , 409,523" href="/cgi-bin/IMap.asp?map=5054D" alt="">
            <area shape="rect" coords="409,496 , 448,523" href="/cgi-bin/IMap.asp?map=5154C" alt="">
            <area shape="rect" coords="448,497 , 488,523" href="/cgi-bin/IMap.asp?map=5154D" alt="">
            <area shape="rect" coords="488,498 , 525,523" href="/cgi-bin/IMap.asp?map=5254C" alt="">
            <area shape="rect" coords="525,497 , 565,522" href="/cgi-bin/IMap.asp?map=5254D" alt="">
            <area shape="rect" coords="565,496 , 604,523" href="/cgi-bin/IMap.asp?map=5354C" alt="">
            <area shape="rect" coords="604,497 , 644,523" href="/cgi-bin/IMap.asp?map=5354D" alt="">
            <area shape="rect" coords="644,497 , 682,522" href="/cgi-bin/IMap.asp?map=5454C" alt="">
            <area shape="rect" coords="682,497 , 723,522" href="/cgi-bin/IMap.asp?map=5454D" alt="">
            <area shape="rect" coords="723,497 , 762,523" href="/cgi-bin/IMap.asp?map=5554C" alt="">
            <area shape="rect" coords="762,497 , 800,523" href="/cgi-bin/IMap.asp?map=5554D" alt="">
            <area shape="rect" coords="801,497 , 840,523" href="/cgi-bin/IMap.asp?map=5654C" alt="">
            <area shape="rect" coords="839,497 , 879,523" href="/cgi-bin/IMap.asp?map=5654D" alt="">
            <area shape="rect" coords="878,497 , 918,523" href="/cgi-bin/IMap.asp?map=5754C" alt="">
            <area shape="rect" coords="290,523 , 330,549" href="/cgi-bin/IMap.asp?map=4953B" alt="">
            <area shape="rect" coords="329,523 , 370,549" href="/cgi-bin/IMap.asp?map=5053A" alt="">
            <area shape="rect" coords="370,523 , 409,549" href="/cgi-bin/IMap.asp?map=5053B" alt="">
            <area shape="rect" coords="409,523 , 447,549" href="/cgi-bin/IMap.asp?map=5153A" alt="">
            <area shape="rect" coords="447,522 , 488,549" href="/cgi-bin/IMap.asp?map=5153B" alt="">
            <area shape="rect" coords="488,523 , 526,549" href="/cgi-bin/IMap.asp?map=5253A" alt="">
            <area shape="rect" coords="526,523 , 566,549" href="/cgi-bin/IMap.asp?map=5253B" alt="">
            <area shape="rect" coords="565,522 , 605,549" href="/cgi-bin/IMap.asp?map=5353A" alt="">
            <area shape="rect" coords="605,523 , 644,549" href="/cgi-bin/IMap.asp?map=5353B" alt="">
            <area shape="rect" coords="643,522 , 683,549" href="/cgi-bin/IMap.asp?map=5453A" alt="">
            <area shape="rect" coords="682,522 , 723,549" href="/cgi-bin/IMap.asp?map=5453B" alt="">
            <area shape="rect" coords="723,522 , 761,549" href="/cgi-bin/IMap.asp?map=5553A" alt="">
            <area shape="rect" coords="761,523 , 800,549" href="/cgi-bin/IMap.asp?map=5553B" alt="">
            <area shape="rect" coords="800,523 , 839,549" href="/cgi-bin/IMap.asp?map=5653A" alt="">
            <area shape="rect" coords="839,523 , 878,549" href="/cgi-bin/IMap.asp?map=5653B" alt="">
            <area shape="rect" coords="878,522 , 918,549" href="/cgi-bin/IMap.asp?map=5753A" alt="">
            <area shape="rect" coords="251,548 , 291,575" href="/cgi-bin/IMap.asp?map=4953C" alt="">
            <area shape="rect" coords="290,547 , 330,574" href="/cgi-bin/IMap.asp?map=4953D" alt="">
            <area shape="rect" coords="329,548 , 369,574" href="/cgi-bin/IMap.asp?map=5053C" alt="">
            <area shape="rect" coords="369,548 , 408,575" href="/cgi-bin/IMap.asp?map=5053D" alt="">
            <area shape="rect" coords="409,548 , 448,575" href="/cgi-bin/IMap.asp?map=5153C" alt="">
            <area shape="rect" coords="448,547 , 488,574" href="/cgi-bin/IMap.asp?map=5153D" alt="">
            <area shape="rect" coords="488,547 , 526,575" href="/cgi-bin/IMap.asp?map=5253C" alt="">
            <area shape="rect" coords="526,548 , 566,575" href="/cgi-bin/IMap.asp?map=5253D" alt="">
            <area shape="rect" coords="566,547 , 605,575" href="/cgi-bin/IMap.asp?map=5353C" alt="">
            <area shape="rect" coords="605,547 , 644,575" href="/cgi-bin/IMap.asp?map=5353D" alt="">
            <area shape="rect" coords="644,547 , 682,575" href="/cgi-bin/IMap.asp?map=5453C" alt="">
            <area shape="rect" coords="682,547 , 722,575" href="/cgi-bin/IMap.asp?map=5453D" alt="">
            <area shape="rect" coords="723,547 , 762,575" href="/cgi-bin/IMap.asp?map=5553C" alt="">
            <area shape="rect" coords="762,548 , 801,574" href="/cgi-bin/IMap.asp?map=5553D" alt="">
            <area shape="rect" coords="801,547 , 840,575" href="/cgi-bin/IMap.asp?map=5653C" alt="">
            <area shape="rect" coords="840,547 , 879,575" href="/cgi-bin/IMap.asp?map=5653D" alt="">
            <area shape="rect" coords="252,574 , 291,599" href="/cgi-bin/IMap.asp?map=4952A" alt="">
            <area shape="rect" coords="291,573 , 330,600" href="/cgi-bin/IMap.asp?map=4952B" alt="">
            <area shape="rect" coords="330,574 , 370,600" href="/cgi-bin/IMap.asp?map=5052A" alt="">
            <area shape="rect" coords="369,573 , 409,600" href="/cgi-bin/IMap.asp?map=5052B" alt="">
            <area shape="rect" coords="409,574 , 448,600" href="/cgi-bin/IMap.asp?map=5152A" alt="">
            <area shape="rect" coords="449,574 , 488,599" href="/cgi-bin/IMap.asp?map=5152B" alt="">
            <area shape="rect" coords="488,573 , 526,600" href="/cgi-bin/IMap.asp?map=5252A" alt="">
            <area shape="rect" coords="526,574 , 566,600" href="/cgi-bin/IMap.asp?map=5252B" alt="">
            <area shape="rect" coords="566,574 , 605,600" href="/cgi-bin/IMap.asp?map=5352A" alt="">
            <area shape="rect" coords="604,573 , 643,599" href="/cgi-bin/IMap.asp?map=5352B" alt="">
            <area shape="rect" coords="643,574 , 683,599" href="/cgi-bin/IMap.asp?map=5452A" alt="">
            <area shape="rect" coords="682,574 , 723,599" href="/cgi-bin/IMap.asp?map=5452B" alt="">
            <area shape="rect" coords="723,574 , 762,600" href="/cgi-bin/IMap.asp?map=5552A" alt="">
            <area shape="rect" coords="762,573 , 801,600" href="/cgi-bin/IMap.asp?map=5552B" alt="">
            <area shape="rect" coords="800,574 , 839,599" href="/cgi-bin/IMap.asp?map=5652A" alt="">
            <area shape="rect" coords="839,573 , 878,599" href="/cgi-bin/IMap.asp?map=5652B" alt="">
            <area shape="rect" coords="252,599 , 291,625" href="/cgi-bin/IMap.asp?map=4952C" alt="">
            <area shape="rect" coords="290,599 , 329,625" href="/cgi-bin/IMap.asp?map=4952D" alt="">
            <area shape="rect" coords="330,599 , 370,625" href="/cgi-bin/IMap.asp?map=5052C" alt="">
            <area shape="rect" coords="369,599 , 408,626" href="/cgi-bin/IMap.asp?map=5052D" alt="">
            <area shape="rect" coords="409,599 , 448,625" href="/cgi-bin/IMap.asp?map=5152C" alt="">
            <area shape="rect" coords="447,598 , 488,626" href="/cgi-bin/IMap.asp?map=5152D" alt="">
            <area shape="rect" coords="488,598 , 526,626" href="/cgi-bin/IMap.asp?map=5252C" alt="">
            <area shape="rect" coords="526,598 , 566,626" href="/cgi-bin/IMap.asp?map=5252D" alt="">
            <area shape="rect" coords="566,598 , 605,626" href="/cgi-bin/IMap.asp?map=5352C" alt="">
            <area shape="rect" coords="604,598 , 644,626" href="/cgi-bin/IMap.asp?map=5352D" alt="">
            <area shape="rect" coords="644,598 , 683,626" href="/cgi-bin/IMap.asp?map=5452C" alt="">
            <area shape="rect" coords="682,598 , 723,625" href="/cgi-bin/IMap.asp?map=5452D" alt="">
            <area shape="rect" coords="723,599 , 762,625" href="/cgi-bin/IMap.asp?map=5552C" alt="">
            <area shape="rect" coords="761,599 , 800,625" href="/cgi-bin/IMap.asp?map=5552D" alt="">
            <area shape="rect" coords="801,599 , 839,625" href="/cgi-bin/IMap.asp?map=5652C" alt="">
            <area shape="rect" coords="839,598 , 878,626" href="/cgi-bin/IMap.asp?map=5652D" alt="">
            <area shape="rect" coords="330,624 , 370,652" href="/cgi-bin/IMap.asp?map=5051A" alt="">
            <area shape="rect" coords="369,624 , 409,651" href="/cgi-bin/IMap.asp?map=5051B" alt="">
            <area shape="rect" coords="409,625 , 448,652" href="/cgi-bin/IMap.asp?map=5151A" alt="">
            <area shape="rect" coords="448,625 , 488,652" href="/cgi-bin/IMap.asp?map=5151B" alt="">
            <area shape="rect" coords="487,625 , 526,652" href="/cgi-bin/IMap.asp?map=5251A" alt="">
            <area shape="rect" coords="526,624 , 565,652" href="/cgi-bin/IMap.asp?map=5251B" alt="">
            <area shape="rect" coords="565,625 , 605,652" href="/cgi-bin/IMap.asp?map=5351A" alt="">
            <area shape="rect" coords="605,625 , 643,651" href="/cgi-bin/IMap.asp?map=5351B" alt="">
            <area shape="rect" coords="643,625 , 682,650" href="/cgi-bin/IMap.asp?map=5451A" alt="">
            <area shape="rect" coords="683,625 , 723,652" href="/cgi-bin/IMap.asp?map=5451B" alt="">
            <area shape="rect" coords="723,624 , 761,652" href="/cgi-bin/IMap.asp?map=5551A" alt="">
            <area shape="rect" coords="762,624 , 801,652" href="/cgi-bin/IMap.asp?map=5551B" alt="">
            <area shape="rect" coords="800,624 , 840,651" href="/cgi-bin/IMap.asp?map=5651A" alt="">
            <area shape="rect" coords="839,625 , 878,652" href="/cgi-bin/IMap.asp?map=5651B" alt="">
            <area shape="rect" coords="369,650 , 409,677" href="/cgi-bin/IMap.asp?map=5051D" alt="">
            <area shape="rect" coords="409,650 , 448,678" href="/cgi-bin/IMap.asp?map=5151C" alt="">
            <area shape="rect" coords="448,651 , 488,678" href="/cgi-bin/IMap.asp?map=5151D" alt="">
            <area shape="rect" coords="488,651 , 525,677" href="/cgi-bin/IMap.asp?map=5251C" alt="">
            <area shape="rect" coords="526,651 , 566,678" href="/cgi-bin/IMap.asp?map=5251D" alt="">
            <area shape="rect" coords="566,651 , 605,677" href="/cgi-bin/IMap.asp?map=5351C" alt="">
            <area shape="rect" coords="605,650 , 644,678" href="/cgi-bin/IMap.asp?map=5351D" alt="">
            <area shape="rect" coords="644,650 , 683,677" href="/cgi-bin/IMap.asp?map=5451C" alt="">
            <area shape="rect" coords="682,652 , 722,677" href="/cgi-bin/IMap.asp?map=5451D" alt="">
            <area shape="rect" coords="722,651 , 761,677" href="/cgi-bin/IMap.asp?map=5551C" alt="">
            <area shape="rect" coords="762,651 , 801,678" href="/cgi-bin/IMap.asp?map=5551D" alt="">
            <area shape="rect" coords="800,651 , 840,678" href="/cgi-bin/IMap.asp?map=5651C" alt="">
            <area shape="rect" coords="840,651 , 878,678" href="/cgi-bin/IMap.asp?map=5651D" alt="">
            <area shape="rect" coords="408,677 , 448,703" href="/cgi-bin/IMap.asp?map=5150A" alt="">
            <area shape="rect" coords="447,677 , 488,703" href="/cgi-bin/IMap.asp?map=5150B" alt="">
            <area shape="rect" coords="488,676 , 526,703" href="/cgi-bin/IMap.asp?map=5250A" alt="">
            <area shape="rect" coords="525,676 , 566,703" href="/cgi-bin/IMap.asp?map=5250B" alt="">
            <area shape="rect" coords="566,677 , 604,703" href="/cgi-bin/IMap.asp?map=5350A" alt="">
            <area shape="rect" coords="605,677 , 644,703" href="/cgi-bin/IMap.asp?map=5350D" alt="">
            <area shape="rect" coords="643,676 , 682,702" href="/cgi-bin/IMap.asp?map=5450A" alt="">
            <area shape="rect" coords="683,676 , 723,703" href="/cgi-bin/IMap.asp?map=5450B" alt="">
            <area shape="rect" coords="723,676 , 762,703" href="/cgi-bin/IMap.asp?map=5550A" alt="">
            <area shape="rect" coords="762,676 , 801,703" href="/cgi-bin/IMap.asp?map=5550B" alt="">
            <area shape="rect" coords="801,676 , 840,703" href="/cgi-bin/IMap.asp?map=5650A" alt="">
            <area shape="rect" coords="840,677 , 879,703" href="/cgi-bin/IMap.asp?map=5650B" alt="">
            <area shape="rect" coords="487,702 , 525,728" href="/cgi-bin/IMap.asp?map=5250C" alt="">
            <area shape="rect" coords="525,702 , 565,728" href="/cgi-bin/IMap.asp?map=5250D" alt="">
            <area shape="rect" coords="565,702 , 604,729" href="/cgi-bin/IMap.asp?map=5350C" alt="">
            <area shape="rect" coords="603,701 , 643,729" href="/cgi-bin/IMap.asp?map=5350D" alt="">
            <area shape="rect" coords="643,702 , 682,729" href="/cgi-bin/IMap.asp?map=5450C" alt="">
            <area shape="rect" coords="682,701 , 722,729" href="/cgi-bin/IMap.asp?map=5450D" alt="">
            <area shape="rect" coords="525,728 , 565,755" href="/cgi-bin/IMap.asp?map=5249B" alt="">
        </map> '''

We can use python's beautifulsoup library to extract the facet numbers, then construct the detailed map links since they all follow the same pattern as seen below.

from bs4 import BeautifulSoup

soup = BeautifulSoup(iMap, 'html.parser')
facet_maps = soup.find_all("area")

facet_number = [ f['href'].split('=')[-1] for f in facet_maps ]
detailed_map = [ 'https://public.hcad.org/iMaps/Tiles/Color/' + f['href'].split('=')[-1] + str(a) + '.pdf' for f in facet_maps for a in range(1, 13) ]


appr_dist = 'Houston'
appr_dist_link = 'https://public.hcad.org/maps/Houston.asp'


df = pd.DataFrame([])
# df['Facet Number'] = facet_number
df['Detailed map'] = detailed_map
df['Appraisal Districts'] = appr_dist
df['Link'] = appr_dist_link



The final output is similar to the screen above.

Cheers!

Saturday, November 19, 2022

Scrape online academic materials using python

 You know it can be a boring task to manually collect academic material you found online. In this blog post, I will demonstrate how I use python to collect some academic thesis, journals, and other materials for my profession.


Online Scientific Research Journals: 

Here my professor wants to have all the journals and their details published by "Scientific Research and Community Publishers" onlinescientificresearch.com neatly arranged in a spreadsheet table.

The specific details required are the journal name/title, the page URL, the description, cover image and ISSN number.

All the details should be organized in a spreadsheet as seen below.


The code:

import json
import requests
import pandas as pd
from bs4 import BeautifulSoup



# Section 1: Scrape journals page URLs and thumbnail images

url = 'https://www.onlinescientificresearch.com/journals.php'

# Get user-agent from: http://www.useragentstring.com/
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

response = requests.get(url, headers=headers)
html = response.text

soup = BeautifulSoup(html, 'html.parser')
journals = soup.find_all("div", {'class':'col-12 col-sm-6 col-lg-3'})

print(len(journals))
# ---------------------------------------------------------------

# Section 2: Extract paths to journals URL and thumbnail image...

url_list = []
image_list = []

for j in journals:
    url = j.find('a')['href']
    img = j.find('img')['src']
    
    url_list.append(url)
    image_list.append(img)
    
print('Done...')


# ---------------------------------------------------------------
# Section 3: Create dataframe and construct other details...

df = pd.DataFrame([url_list, image_list]).T
df.columns = ['Journal URL', 'Journal IMAGE URL']
# -------------------------------------
####### Construct Journal Name #######
df['Journal Name'] = df['Journal URL'].apply(lambda row: row.split('/')[-1].replace('.php', '').replace('-', ' ').title())


####### Construct Journal Description #######
def get_journal_descr(url):
    # Get user-agent from: http://www.useragentstring.com/
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

    response = requests.get(url, headers=headers)
    html = response.text
    
    soup = BeautifulSoup(html, 'html.parser')
    journal_descr = soup.find("div", {'class':'card-body'})
    
    return journal_descr.text
# -------------------------------------
# Scrape Journal description into a list 
j_descr_list = []
i = 1

for url in df['Journal URL']:
    print(i, 'Processing...', url)
    j_descr = get_journal_descr(url)
    
    j_descr_list.append((url, j_descr))
    i = i+1

desc_df = pd.DataFrame(j_descr_list)
# -------------------------------------

# We have to access each journal url page to get its description...
# df['Journal description'] = df['Journal URL'].apply(lambda url: get_journal_descr(url))
df['Journal description'] = desc_df[1]


####### Construct Journal ISSN #######
# We have to use OCR on the journal thumb nail to get its ISSN...
# Using OCR API at: https://ocr.space/ocrapi....

headers = {
    'apikey': 'helloworld', # 'helloworld'
    'content-type': 'application/x-www-form-urlencoded',
}

issn_list = []

for thumbnail in df['Journal IMAGE URL']:
    print('Processing....', thumbnail)
    
    data = f'isOverlayRequired=true&url={thumbnail}&language=eng'

    response = requests.post('https://api.ocr.space/Parse/Image', headers=headers, data=data, verify=False)

    result = json.loads(response.content.decode()) # Convert the result to dictionary using json.loads() function
    # type(result)

    # Check the dict keys, the ISSN is in: ParsedResults >> 0 >> ParsedText
    issn = result['ParsedResults'][0]['ParsedText'].strip().split('\r\n')[-1]

    issn_list.append(issn)

df['Journal ISSN'] = issn_list

df
Extracting the journal ISSN was definitely the trickiest part as it requires working with OCR API.



M.Sc. in GIST Theses

Master of Science (Geographic Information Science and Technology) Theses by University of Southern California. 


Here our professor wants the thesis details arranged in a table seen above.

Lets start by inspecting the html tags on the web page.

Here I copied the parent div tag that contains the needed data into a local html file. With this we don't need to send request to the website.

import pandas as pd
from bs4 import BeautifulSoup

# Copy the parent div tag into a html/txt file...
html_file = r"C:\Users\Yusuf_08039508010\Documents\Jupyter_Notebook\2022\M.S. IN GIST THESES\M.S. IN GIST THESES.HTML"

# Use BeautifulSoup to read the html div tag....
with open(html_file, encoding='utf-8') as f:
    div_data = f.read()

soup = BeautifulSoup(div_data, 'html.parser')

thesis_years = soup.find_all("h3")

thesis_authors = soup.find_all("strong")
thesis_authors = [ a.text for a in thesis_authors ]

thesis_topics = soup.find_all("em")
thesis_topics = [ t.text for t in thesis_topics ]

thesis_advisor = soup.find_all("p")
thesis_advisor = [ a.text for a in thesis_advisor if 'Advisor:' in a.text ]

thesis_pdf = soup.find_all("a")
thesis_pdf = [ link.get('href') for link in thesis_pdf if 'Abstract Text' not in link.text ]

# --------------------------------------------
df = pd.DataFrame(thesis_authors, columns=['Author'])
df['Topic'] = thesis_topics
df['Advisor'] = thesis_advisor
df['PDF Link'] = thesis_pdf

df

The code below will download the PDF files to local disc using the requests library.
i = 1
for indx, row in df.iterrows():
    link = row['PDF Link']
    print('Processsing...', link)

    pdf_name = str(i) +'_'+ link.split('/')[-1]
    pdf_file = requests.get(link, timeout=10).content

    with open( f'Thesis PDF\\{pdf_name}', 'wb' ) as f:
        f.write(pdf_file)
        
    i += 1
    # break


print('Finished...')





Journal - Nigerian Institution of Surveyors



This was little bit trick because the web page had inconsistent html tags.
import requests
import pandas as pd
from bs4 import BeautifulSoup


url = 'https://nisngr.net/journal/'
response = requests.get(url, verify=False)
html = response.text
# ----------------------------


soup = BeautifulSoup(html, 'html.parser')
div_boxes = soup.find_all("div", {'class':'wpb_text_column wpb_content_element'})
# ----------------------------


papers_dict = {}
for div in div_boxes:
    papers = div.find_all('a')
    
    for link in papers:
        papers_dict[link.text] = link['href']
# ----------------------------

df = pd.DataFrame([papers_dict]).T
df




Thank you for reading.