1. Post #1
    Gold Member
    AMD 32's Avatar
    February 2007
    648 Posts
    I've been looking around but I can't really find a solid resource for using the Google Maps API with a custom image. All I can find are things relating to overlays when I don't want to overlay anything onto Earth, I want to specify a custom map.
    This site here is pretty much exactly what I want to be able to achieve:
    http://www.gta4.net/map/

    I just can't find the documentation that relates to specifically what I want to do. Sometimes I find a resource that might be related, like using Google Maps for an image but it always seems like they're using an outdated API and they don't talk about how to add markers.
    So does anybody have any idea how I can achieve this?

  2. Post #2
    Blue and Proud Of It.
    Dennab
    September 2011
    961 Posts
    Not sure what you are really looking for by Google have an excellent Developer's section.

    https://developers.google.com/maps/

  3. Post #3
    Gold Member
    AMD 32's Avatar
    February 2007
    648 Posts
    I pretty much want to provide all the tiles that my Google Maps instance is going to use. I can't find the right piece of documentation to help me with this. If you have a look at that GTA 4 map, it's using Google Maps but it's not using their Earth tiles at all. It's using fully custom tiles that they've specified. I can't find any resources that help me do what they're doing.

  4. Post #4
    Blue and Proud Of It.
    Dennab
    September 2011
    961 Posts
    Why not email their webmaster?
    Reply With Quote Edit / Delete Reply Windows 7 United Kingdom Show Events Dumb Dumb x 4Funny Funny x 1 (list)

  5. Post #5
    SteamDB
    Marlamin's Avatar
    November 2007
    10,741 Posts
    I made this a while back: http://marlamin.com/gmaps/

    If you want to I can put up a small explanation of how I did it, since you probably don't want to view source of that.

    EDIT: Meh, screw it. Doing a little write-up anyways because I'm that nice. Check back here in a while.

    Tiles
    You start with making tiles that Google Maps works with. Format for the filename structure is as follows:
    zoom_x_y.(png/jpg)

    To generate such a metric shitton of files you need to start out with a (as high res as possible) base image which you want to slice up. I use stitched versions of WoW's minimaps for this but it can be done with whatever pic you want.

    Open up your image in Photoshop (required for this step), make sure everything looks ok and there are no mistakes in the image.

    Now to the interesting stuff. For tiling up the image we're going to be utilizing Photoshop's scripting environment.
    Grab this script. There are some basic things you might want to configure, but as it is currently it's set for 7 zoom levels and saving as PNG. The only thing you might want to change is the folder you want to save the tiles to (make sure you've made one).
    If you want to save up space, make sure the "background" of your image is transparent. In my case it's the sea. If it's transparent in Photoshop it won't actually generate tiles for that saving up a lot of space for big images.
    Save the script somewhere, go back into Photoshop and navigate to the Scripts menu.



    Press browse and select the script. This will start generating tiles immediately, and depending on the size of your image this might take a while. If everything is going as it should tiles should be appearing the in the folder you specified earlier.

    After it's done, upload the tiles to your web hosting (I assume you have one).

    Now. For the good part!

    Making your map
    I started out with a very complicated and extremely crappy map held together by duct tape and nails. Now, don't worry. It's quite easy now!

    Don't bother copy pasting stuff already, just copy paste the full code at the end of this post over. This part is only explaining of some things.

    First off, start by embedding Google's API.
    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    

    Now, let's create our own custom map type! This stuff isn't -that- interesting yet.

    <script>
    function CustomMapType() {
    }
    CustomMapType.prototype.tileSize = new google.maps.Size(256,256); 
    CustomMapType.prototype.maxZoom = 7;
    

    This however, is where it gets interesting.

    The baseURL is where it should load it's tiles from. This is pretty straight forward. If your eventual tile image would be at http://tile1.marlam.info/tiles/azeroth/15689/1_0_0.png for example, the URL should be http://tile1.marlam.info/tiles/azeroth/15689/.

    You can also set the background color of the DIV here to whatever you want. I have it set to the color of the sea.
    CustomMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
        var div = ownerDocument.createElement('DIV');
        var baseURL = 'http://tile1.marlam.info/tiles/azeroth/15689/';
        baseURL += zoom + '_' + coord.x + '_' + coord.y + '.png';
        div.style.width = this.tileSize.width + 'px';
        div.style.height = this.tileSize.height + 'px';
        div.style.backgroundColor = '#1B2D33';
        div.style.backgroundImage = 'url(' + baseURL + ')';
        return div;
    };
    
    CustomMapType.prototype.name = "Custom";
    CustomMapType.prototype.alt = "Tile Coordinate Map Type";
    var map;
    var CustomMapType = new CustomMapType();
    </script>
    

    Next we'll be give some options to the map.

    minZoom is the minimum available zoom level. I have it set to 2 because 1 is just this:



    (which is useless).

    maxZoom is exactly what you think it is.
    isPng says that the images are PNG/transparent. If you generated JPGs set this to false.
    mapTypeControl and streetViewControl are those default controls you see on the normal Google Maps. This is mostly useless for custom maps.
    center are the LatLng coordinates for what the center of the map should be when it loads.
    zoom is the zoom level that the map should be when it loads.
    The mapTypeControlOptions just override the above mentioned mapTypeControl to make sure no issues come up.

    <script>
    function initialize() {
      var mapOptions = {
          minZoom: 2,
        maxZoom: 7,
        isPng: true,
          mapTypeControl: false,
          streetViewControl: false,
            center: new google.maps.LatLng(65.07,-56.08),     
          zoom: 3,
        mapTypeControlOptions: {
          mapTypeIds: ['custom', google.maps.MapTypeId.ROADMAP],
          style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
        }
      };
    
    

    Now you must set the map to a div. In my case the div is map_canvas and spans the whole page. After that you set it to your custom map type and voila!

    map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
    map.mapTypes.set('custom',CustomMapType);
    map.setMapTypeId('custom');
    

    And don't forget calling the initialize function on pageload:

    <body onload="initialize()"> 
    



    Here's the full code I used to make this page. Feel free to copy/paste/steal whatever.

    <!DOCTYPE html>
    <html> 
    <head> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <style type="text/css">
          html { height: 100% }
          body { height: 100%; margin: 0px; padding: 0px }
          #map_canvas { height: 100%; z-index: 0;}
          #gmnoprint {width: auto;}
    </style>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
    <title>Google Map of the WoW World</title> 
    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script>
    function CustomMapType() {
    }
    CustomMapType.prototype.tileSize = new google.maps.Size(256,256);
    CustomMapType.prototype.maxZoom = 7;
    CustomMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
        var div = ownerDocument.createElement('DIV');
        var baseURL = 'http://tile1.marlam.info/tiles/azeroth/15689/';
        baseURL += zoom + '_' + coord.x + '_' + coord.y + '.png';
        div.style.width = this.tileSize.width + 'px';
        div.style.height = this.tileSize.height + 'px';
        div.style.backgroundColor = '#1B2D33';
        div.style.backgroundImage = 'url(' + baseURL + ')';
        return div;
    };
    
    CustomMapType.prototype.name = "Custom";
    CustomMapType.prototype.alt = "Tile Coordinate Map Type";
    var map;
    var CustomMapType = new CustomMapType();
    function initialize() {
      var mapOptions = {
          minZoom: 2,
        maxZoom: 7,
        isPng: true,
          mapTypeControl: false,
          streetViewControl: false,
            center: new google.maps.LatLng(65.07,-56.08),     
          zoom: 3,
        mapTypeControlOptions: {
          mapTypeIds: ['custom', google.maps.MapTypeId.ROADMAP],
          style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
        }
      };
    map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
    map.mapTypes.set('custom',CustomMapType);
    map.setMapTypeId('custom');
    }
    </script>
    </head> 
    <body onload="initialize()"> 
    <div id="map_canvas" style="background: #1B2D33;"></div> 
    </body>
    </html> 


    Phew. That should do the trick. If it does not, feel free to send a PM. I'll also check back here later.
    Reply With Quote Edit / Delete Reply Windows 7 Netherlands Show Events Winner Winner x 36Programming King Programming King x 5Friendly Friendly x 1Artistic Artistic x 1 (list)

  6. Post #6
    Gold Member
    AMD 32's Avatar
    February 2007
    648 Posts
    That's exactly what I need, thanks for the help! So far I've got the custom map working but I just need the tiles and you forgot to add the script link :(

  7. Post #7
    SteamDB
    Marlamin's Avatar
    November 2007
    10,741 Posts
    That's what I get for copy pasting it between several applications.

    Oh well, here you go.


    http://marlamin.com/u/2012.05.17-23.19.19.log

    Save as tiler.jsx.
    Reply With Quote Edit / Delete Reply Windows 7 Netherlands Show Events Friendly Friendly x 2 (list)

  8. Post #8
    Gold Member
    AMD 32's Avatar
    February 2007
    648 Posts
    Awesome, thanks for the help! It's working exactly as it should.
    http://teamfackin.com/moocow/dayz/map/
    Reply With Quote Edit / Delete Reply Windows 7 United Kingdom Show Events Programming King Programming King x 1 (list)

  9. Post #9
    SteamDB
    Marlamin's Avatar
    November 2007
    10,741 Posts
    Great job, looks better than anything I ever made!

  10. Post #10
    Piit2KX's Avatar
    December 2012
    1 Posts
    awesome... ive been lookin for something like that for weeks!
    but is there any option to add markers from a xml-file?
    Reply With Quote Edit / Delete Reply Windows 8 Germany Show Events Late Late x 2 (list)

  11. Post #11
    SteamDB
    Marlamin's Avatar
    November 2007
    10,741 Posts
    awesome... ive been lookin for something like that for weeks!
    but is there any option to add markers from a xml-file?
    You can parse the XML in JavaScript and generate markers from that. See here.

  12. Post #12

    April 2013
    2 Posts
    Not a programmer, or that familiar with Map API.

    I followed the instructions in this thread, but still having issues.

    http://burninglegion.nfergusonart.com/map

    This should be one image, but it doesn't seem to be getting put back together.

    This is the script I used:
    Code:
    /*  Tile Carver for Photoshop (modified by Nate, only tested in CS3)
      Created by Will James 
      http://onNYTurf.com
      Transparency option added by
      Curtis Wyatt
      http://gocalipso.com/
      Hacked apart and updated to add support for creating multiple zoom levels at once
      Automatically adds extra tiles/pixels where needed
      Can save as PNG, JPEG, and/or GIF
      Now operates much faster with multiple layers/transparencies
      Nate Bundy
      http://www.lemonrage.com/
    */
    
    //**** YOU SHOULD CUSTOMIZE THE FOLLOWING VARIABLE DEPENDING ON YOUR NEED ****
    var HighestZoomLevel = 7; // Enter the highest zoom level we are creating tiles for (should be less than OrgZoom; technically the  script should be able to handle values larger as well, but your image quality will suffer)
    var LowestZoomLevel = 1; // Enter the last zoom level we want to create tiles for (must be <= HighestZoomLevel for the script to do anything)
    
    var FolderPath = "C:/Map/";  //<-- path to where we will save our tiles
    
    // We start with the coordinates, zoom, and width of an upper left corner tile and generate everything from there
    // We can calculate new tile values from these values for any zoom level without having to look up these details for each.
    var OrgX = 1;   // the Google Maps X value of the tile at the top left corner of your Photoshop document
    var OrgY = 1;   // the Google Maps Y value of the tile at the top left corner of your Photoshop document
    var OrgZoomLevel = 7;   // the Google Maps zoom level of your Photoshop document (for best results, you will need to resize your  Photoshop document to match a zoom level as closely as possible before running this script)
    var PixelWidth = 256; // Your width and height should be 256 unless you override Google's default in a custom map type
    var PixelHeight = 256;
    
    // set each file type to true that you wish the script to save out. you may save out all three at the same time if you wish
    var saveJPEG = false;
    var savePNG = true;
    var saveGIF = false;
    
    // Note (by Nate): I've dramatically increased the speed of the transparent path. It's even faster than the old transparency=false  path now. Taking unnecessary snapshots was slowing the transparent path down quite a bit. Now the main speed limiter is saving each tile out to disk, and I doubt there's a way to speed that up.
    
    //**** EVERYTHING BEYOND HERE SHOULD NOT BE TOUCHED UNLESS YOU KNOW WHAT YOU ARE DOING!!!
    
    // Exponent Function 
    // we will need these later
    /*function PowMe(a, b){
      var o = a;
      for (n = 1; n < b; n++){ o *= a; }
      if (b==0){ o = 1;    }
      return o;
    };*/
    // why the custom power function? switched to built in Math.pow()
    
    var currentDocument = app.activeDocument; // Run the script on the active document
    
    // via http://www.ps-scripts.com/bb/viewtopic.php?p=343
    function takeSnapshot () { 
       var id686 = charIDToTypeID( "Mk  " ); 
       var desc153 = new ActionDescriptor(); 
       var id687 = charIDToTypeID( "null" ); 
       var ref119 = new ActionReference(); 
       var id688 = charIDToTypeID( "SnpS" ); 
       ref119.putClass( id688 ); 
       desc153.putReference( id687, ref119 ); 
       var id689 = charIDToTypeID( "From" ); 
       var ref120 = new ActionReference(); 
       var id690 = charIDToTypeID( "HstS" ); 
       var id691 = charIDToTypeID( "CrnH" ); 
       ref120.putProperty( id690, id691 ); 
       desc153.putReference( id689, ref120 ); 
       executeAction( id686, desc153, DialogModes.NO ); 
    }
    
    function revertToLastSnapshot() { 
       var docRef = app.activeDocument; 
       var hsObj = docRef.historyStates; 
       var hsLength = hsObj.length; 
       for (var i = hsLength-1; i > -1; i--) { 
           if(hsObj[i].snapshot) { 
               docRef.activeHistoryState = hsObj.getByName('Snapshot ' + i); 
               break;
           }       
       }       
    }
    
    function revertToSnapshot(snapshotID) {
      currentDocument.activeHistoryState = currentDocument.historyStates[snapshotID];
    }
    
    function getLastSnapshotID()
    { 
       var docRef = app.activeDocument; 
       var hsObj = docRef.historyStates; 
       var hsLength = hsObj.length; 
       for (var i = hsLength-1; i > -1; i--) { 
           if(hsObj[i].snapshot) { 
               return i; 
               break;
           }       
       }       
    }
    
    function getVisibleLayers(doc)
    {
    	var tempArray = new Array();
    	for (var i = 0; i < doc.layers.length; i++)
    	{
    		if (doc.layers[i].visible)
    			tempArray.push(i);
    	}
    	return tempArray;
    }
    
    function isLayerEmpty(doc, layer)
    {   
        if (!doc)
            doc = app.activeDocument
        if (!layer)
            layer = doc.activeLayer
        var b = layer.bounds
        var has_extent = (b[0] != b[2]) || (b[1] != b[3])
        return ! has_extent
    }
    
    function visibleLayersEmpty(doc)
    {
    	var bool = true;
    	if (!doc) {
    		doc = app.activeDocument;
    	}
    	for (var i = 0; i < visibleLayers.length; i++)
    	{
    		bool = isLayerEmpty(doc, doc.layers[visibleLayers[i]]);
    		if (!bool)
    			return bool;
    	}
    	return bool;
    }
    
    var startRulerUnits = app.preferences.rulerUnits; // Save the current preferences
    app.preferences.rulerUnits = Units.PIXELS; // Set Photoshop to use pixels
    
    // Find the visible layers
    var visibleLayers = getVisibleLayers(currentDocument);
    
    var ZoomLevel = HighestZoomLevel;
    var LastZoomLevel = OrgZoomLevel;	
    var CurrentX = OrgX;
    var CurrentY = OrgY;
    
    // Take initial snapshot. We'll go back to this once we're finished to leave the document in the state we started
    // TODO: I'm not sure how to delete snapshots, but I'd like to do that in the future as well to leave the document EXACTLY as we opened it
    takeSnapshot();
    var InitialSnapshotID = getLastSnapshotID();
    
    // Do the following for each zoom level the user wants
    while (ZoomLevel >= LowestZoomLevel)
    {
    	// add padding to make starting X and Y tile values divisible by 2^(LastZoomLevel - DesiredZoom)
    	
    	// first, get X and Y values needed for previous zoom level to resize properly to next zoom level we're outputting
    	var ExpectedX = Math.floor(CurrentX / Math.pow(2, LastZoomLevel - ZoomLevel));
    	var NewX = ExpectedX * Math.pow(2, LastZoomLevel - ZoomLevel);
    
    	var ExpectedY = Math.floor(CurrentY / Math.pow(2, LastZoomLevel - ZoomLevel));
    	var NewY = ExpectedY * Math.pow(2, LastZoomLevel - ZoomLevel);
    	
    	var XTilesNeeded = CurrentX - NewX;
    	var YTilesNeeded = CurrentY - NewY;
     
    	// Now add padding for the extra tiles needed
    	currentDocument.resizeCanvas(currentDocument.width.value + (XTilesNeeded * PixelWidth), currentDocument.height.value + (YTilesNeeded * PixelHeight), AnchorPosition.BOTTOMRIGHT);
    
    	CurrentX = ExpectedX;
    	CurrentY = ExpectedY;
    	
    	// Ensure total width and height of canvas is a multiple of PixelWidth and PixelHeight respectively
    	var BottomPaddingNeeded = (Math.ceil(currentDocument.height.value / PixelHeight) * PixelHeight) - currentDocument.height.value;
    	var RightPaddingNeeded = (Math.ceil(currentDocument.width.value / PixelWidth) * PixelWidth) - currentDocument.width.value;
    	currentDocument.resizeCanvas(currentDocument.width.value + RightPaddingNeeded, currentDocument.height.value + BottomPaddingNeeded, AnchorPosition.TOPLEFT);
    	
    	// Add padding to make number of tiles divisible by 2^(LastZoomLevel - DesiredZoom)
    	var NumXTiles = currentDocument.width.value / PixelWidth;
    	var NumYTiles = currentDocument.height.value / PixelHeight;
    	var NumXTilesNeeded = Math.ceil(NumXTiles / Math.pow(2, LastZoomLevel - ZoomLevel)) * Math.pow(2, LastZoomLevel - ZoomLevel);
    	var NumYTilesNeeded = Math.ceil(NumYTiles / Math.pow(2, LastZoomLevel - ZoomLevel)) * Math.pow(2, LastZoomLevel - ZoomLevel);
    	NumXTilesNeeded = NumXTilesNeeded - NumXTiles;
    	NumYTilesNeeded = NumYTilesNeeded - NumYTiles;
    	currentDocument.resizeCanvas(currentDocument.width.value + (NumXTilesNeeded * PixelWidth), currentDocument.height.value + (NumYTilesNeeded * PixelHeight), AnchorPosition.TOPLEFT);
    	NumXTiles = NumXTiles + NumXTilesNeeded;
    	NumYTiles = NumYTiles + NumYTilesNeeded;
    	
    	// Now resize the canvas and image by .5^(LastZoomLevel - ZoomLevel) (Decrease size by 50% for each zoom level)
    	if (ZoomLevel < LastZoomLevel)
    	{
    		var ResizeFactor = Math.pow(0.5, (LastZoomLevel - ZoomLevel));
    		currentDocument.resizeImage(currentDocument.width.value * ResizeFactor, currentDocument.height.value * ResizeFactor);
    	}
    	
    	// Now that we're done resizing the image and canvas, take a snapshot for this zoom level
    	takeSnapshot();
    	var ZoomLevelSnapshotID = getLastSnapshotID();
    	
    	var StartX = CurrentX; 
    	var StartY = CurrentY;
    	
    	var xTiles = parseInt(currentDocument.width.value, 10) / PixelWidth;
    	var yTiles = parseInt(currentDocument.height.value, 10) / PixelHeight;
    	   	
    	var TotalTiles = xTiles * yTiles;  //<-- calculate the total number of tiles
    	
    	// Counters to track which x value and which y value we are on in our image tile grid
    	var xm = 0;
    	var ym = 0;
    	
    	var TileX = StartX; //<-- Set out first Google X value - later used in file name
    	var TileY = StartY; //<-- Set out first Google Y value - later used in file name
    	
    	// Cut 'em up
    	// For each tile we need to make, we repeat each step in this loop
    	for (n=1; n<TotalTiles+1; n++)
    	{            
    		// We cut up tiles column by column
    		// I.E. we cut up all the tiles for a given x value before moving on to the next x value.
    		// We do this by checking if the y value we are on is the last tile in a column 
    		// We compare our y counter to our total y number of Tiles, if they are the same is we do the following
    		if (parseInt(ym, 10) == parseInt(yTiles, 10))
    		{   
    			xm += 1; //<-- Up the x value by 1, i.e. we move over to the next column   
    			ym = 0;  //<-- Reset the y value to 0 so we start back at the top of our new column
    			TileX += 1; //<-- Increase our Google X value for our file name 
    			TileY = StartY;  //We reset our Google Y value for out file name everytime we change columns
    		}
    		
    		// Based on our our TileWidth and TileHeight and the column we are on we determine our selection origin and area values     
    		MyXO = xm*(PixelWidth);
    		MyXL = xm*(PixelWidth)+(PixelWidth);
    		MyYO = ym*(PixelHeight);
    		MyYL = ym*(PixelHeight)+(PixelHeight);                
    						
    		//try {
    			currentDocument.crop(Array(MyXO, MyYO, MyXL, MyYL));
    		/*}
    		catch (e)
    		{
    			alert("xm: " + xm + ", ym: " + ym + ", MyXO: " + MyXO + ", MyYO: " + MyYO + ", MyXL: " + MyXL + ", MyYL: " + MyYL + ", XTiles: " + xTiles + ", YTiles: " + yTiles + "ym == yTiles?: " + (ym == yTiles));
    		}*/
    		
    		if (!visibleLayersEmpty(currentDocument))
    		{
    			//Save New Doc
    			var saveMe = currentDocument;
    								
    			//Save the file
    			if (saveGIF)
    			{
    				//Set path to file and file name
    				saveFile = new File(FolderPath + ZoomLevel + "_" + TileX + "_" + TileY + ".gif");    
    				//Set save options
    				gifSaveOptions = new GIFSaveOptions();
    				gifSaveOptions.colors = 64;
    				gifSaveOptions.dither = Dither.NONE;
    				gifSaveOptions.matte = MatteType.NONE;
    				gifSaveOptions.preserveExactColors = 0;
    				gifSaveOptions.transparency = 1;
    				gifSaveOptions.interlaced = 0;
    				saveMe.saveAs(saveFile, gifSaveOptions, true, Extension.LOWERCASE);
    			}
    			if (savePNG)
    			{
    				//Set path to file and file name
    				saveFile = new File(FolderPath + ZoomLevel + "_" + TileX + "_" + TileY + ".png");    
    				pngSaveOptions = new PNGSaveOptions();
    				pngSaveOptions.interlaced = 0;
    				saveMe.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
    			}
    			if (saveJPEG)
    			{
    				//Set path to file and file name
    				saveFile = new File(FolderPath + ZoomLevel + "_" + TileX + "_" + TileY + ".jpg");    
    				jpegSaveOptions = new JPEGSaveOptions();
    				jpegSaveOptions.formatOpsions = FormatOptions.STANDARDBASELINE;
    				jpegSaveOptions.matte = MatteType.NONE;
    				jpegSaveOptions.quality = 5;				
    				saveMe.saveAs(saveFile, jpegSaveOptions, true, Extension.LOWERCASE);
    			}
    		}
    		revertToSnapshot(ZoomLevelSnapshotID);
    		//saveMe.close(SaveOptions.DONOTSAVECHANGES);
    	
    		//Advance Y counter for next image
    		ym += 1;
    		
    		//Advance Google Y value for next image name
    		TileY += 1;
    	}
    	//revertToLastSnapshot(); 
    	LastZoomLevel = ZoomLevel;
    	ZoomLevel--;
    }
    // Leave the document as we opened it
    revertToSnapshot(InitialSnapshotID);
    
    // Restore application preferences
    app.preferences.rulerUnits = startRulerUnits;
    This is my HTML file:
    Code:
    <!DOCTYPE html>
    <html> 
    <head> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <style type="text/css">
          html { height: 100% }
          body { height: 100%; margin: 0px; padding: 0px }
          #map_canvas { height: 100%; z-index: 0;}
          #gmnoprint {width: auto;}
    </style>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
    <title>Google Map of the WoW World</title> 
    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script>
    function CustomMapType() {
    }
    CustomMapType.prototype.tileSize = new google.maps.Size(256,256);
    CustomMapType.prototype.maxZoom = 7;
    CustomMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
        var div = ownerDocument.createElement('DIV');
        var baseURL = 'http://burninglegion.nfergusonart.com/maptiles/';
        baseURL += zoom + '_' + coord.x + '_' + coord.y + '.png';
        div.style.width = this.tileSize.width + 'px';
        div.style.height = this.tileSize.height + 'px';
        div.style.backgroundColor = '#1B2D33';
        div.style.backgroundImage = 'url(' + baseURL + ')';
        return div;
    };
     
    CustomMapType.prototype.name = "Custom";
    CustomMapType.prototype.alt = "Tile Coordinate Map Type";
    var map;
    var CustomMapType = new CustomMapType();
    function initialize() {
      var mapOptions = {
          minZoom: 2,
        maxZoom: 7,
        isPng: true,
          mapTypeControl: false,
          streetViewControl: false,
            center: new google.maps.LatLng(65.07,-56.08),     
          zoom: 3,
        mapTypeControlOptions: {
          mapTypeIds: ['custom', google.maps.MapTypeId.ROADMAP],
          style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
        }
      };
    map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
    map.mapTypes.set('custom',CustomMapType);
    map.setMapTypeId('custom');
    }
    </script>
    </head> 
    <body onload="initialize()"> 
    <div id="map_canvas" style="background: #1B2D33;"></div> 
    </body>
    </html>
    Reply With Quote Edit / Delete Reply Windows 7 United States Show Events Winner Winner x 2 (list)

  13. Post #13
    Gold Member
    deadeye536's Avatar
    February 2008
    1,452 Posts
    The problem might be with Apache's configuration. It's returning a HTTP 301 to a tile that exists for tiles that shouldn't exist.

    For example:
    http://burninglegion.nfergusonart.co...iles/3_6_0.png
    is redirecting to
    http://burninglegion.nfergusonart.co...iles/3_0_0.png
    Reply With Quote Edit / Delete Reply Linux United States Show Events Informative Informative x 2 (list)

  14. Post #14

    April 2013
    2 Posts
    The problem might be with Apache's configuration. It's returning a HTTP 301 to a tile that exists for tiles that shouldn't exist.

    For example:
    http://burninglegion.nfergusonart.co...iles/3_6_0.png
    is redirecting to
    http://burninglegion.nfergusonart.co...iles/3_0_0.png
    Not sure how to fix that. Is that in the HTML code?

  15. Post #15
    SteamDB
    Marlamin's Avatar
    November 2007
    10,741 Posts
    Not sure how to fix that. Is that in the HTML code?
    It's somewhere in the configuration of your web server.
    Reply With Quote Edit / Delete Reply Windows 7 Netherlands Show Events Agree Agree x 1 (list)

  16. Post #16

    June 2013
    2 Posts
    Just signed up to first of all say THANK YOU, I've been trying to figure this out for a long time, and have given up at least twice and moved to other solutions instead, but this is EXACTLY what I was hoping for. One question, though. Is it possible to lock the size of the map so you can't over-scroll into emptiness off the edge of the map? I get that normally, a map would go around the world without "edges" but for custom maps, often you do have hard edges that don't loop, and it would be really nice to be able to define them. I'm looking to use this for my walkthrough site for a Legend of Zelda ROM hack called Parallel Worlds. The site is here, currently using a Flash-based map viewer called WorldKit, but you can see my current GMaps test page here. Try panning to the south of the house and you'll very quickly see what I'm asking about as far as map edges...

  17. Post #17
    SteamDB
    Marlamin's Avatar
    November 2007
    10,741 Posts
    Just signed up to first of all say THANK YOU, I've been trying to figure this out for a long time, and have given up at least twice and moved to other solutions instead, but this is EXACTLY what I was hoping for. One question, though. Is it possible to lock the size of the map so you can't over-scroll into emptiness off the edge of the map? I get that normally, a map would go around the world without "edges" but for custom maps, often you do have hard edges that don't loop, and it would be really nice to be able to define them. I'm looking to use this for my walkthrough site for a Legend of Zelda ROM hack called Parallel Worlds. The site is here, currently using a Flash-based map viewer called WorldKit, but you can see my current GMaps test page here. Try panning to the south of the house and you'll very quickly see what I'm asking about as far as map edges...
    I don't know this, sorry. Let me know if you find out, though.

  18. Post #18

    June 2013
    2 Posts
    Looks like the answer is here, but it's not working for me. I think that I might not have set up my projection definitions correctly. It's working for me in the Y direction, but not the X.

  19. Post #19
    SteamDB
    Marlamin's Avatar
    November 2007
    10,741 Posts
    For those examining my examples above, Google now has it's own implementation of this in the ImageMapType. It'll give you smooth zooming and stuff.

    You can check out my map without (the example in above posts) and with (only map is done, other features are not) the Google ImageMapType to check out the differences.

  20. Post #20
    -FP
    -FP's Avatar
    July 2013
    2 Posts
    Thanks Marlamin.

    I managed to create my map with your example, even made it to generate the map coordinates and update it in the URL, something like this: mymapsite.com/?x=66.66&y=-128.46&z=5

    Now the issue is that I'm not really sure how to "read" that coordinates in the url to go to that location when somebody copies and pastes it.

    Any tip for that?

  21. Post #21
    -FP
    -FP's Avatar
    July 2013
    2 Posts
    Never mind. Used this function to read the coordinates:

    Code:
    function getCoordinates(coordinate)
    {
           var query = window.location.search.substring(1);
           var vars = query.split("&");
           for (var i=0;i<vars.length;i++) {
                   var pair = vars[i].split("=");
                   if(pair[0] == coordinate){return pair[1];}
           }
           return (false);
    }
    And then passed the values to the initialize function.
    Reply With Quote Edit / Delete Reply Windows 7 Spain Show Events Friendly Friendly x 1 (list)

  22. Post #22

    July 2013
    1 Posts
    Does anyone know how to add touch-events on the map?
    I want to use this on mobile phones and tablets

  23. Post #23

    October 2013
    1 Posts
    Sorry to bring an old thread back to life but I;'m trying to create my own custom map for GTA V. I got it to work but it displays 4 maps when completely zoomed out, so I thought I would try and use the API v3 and that doesn't work at all.

    I can't find any tutorials which go in the depth that you have in this thread when it comes to changing the actual map. I used your base code and only changed the title and baseURL. Is there anything else I can change to get this working proper? Any advice would be greatly appreciated.

    my domain is currently http://www.GTAMap.net

    EDIT: Okay some how I have fixed that but I have a yellow border around it which seems to be be created by the script.

    EDIT: Doesn't matter at all now. Was having a lot of problems yesterday and now I do the same thing and it works. Very strange. Thanks for this awesome post though, wouldn't have got this far without it!

  24. Post #24

    January 2014
    1 Posts
    post removed
    Reply With Quote Edit / Delete Reply Windows 7 Canada Show Events Dumb Dumb x 2 (list)