== Tracker urls formatting ==
[blender-addons-contrib.git] / io_import_LRO_Lola_MGS_Mola_img.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 bl_addon_info = {
20     "name": "LRO Lola & MGS Mola img Importer",
21     "author": "ValterVB",
22     "version": (1, 1, 3),
23     "blender": (2, 5, 6),
24     "api": 34043,
25     "location": "3D window > Tool Shelf",
26     "description": "Import DTM from LRO Lola and MGS Mola",
27     "warning": "May consume a lot of memory",
28     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
29         "Scripts/Import-Export/NASA_IMG_Importer",
30     "tracker_url":"http://projects.blender.org/tracker/index.php?"\
31         "func=detail&aid=25462",
32     "category": "Import-Export"}
33
34
35 #***********************************************************************
36 #ver. 0.0.1: -First version
37 #ver. 0.0.2: -Add check on path and file
38 #            -Check on selected coordinates more complete
39 #ver. 1.1.0: -Optimized for less memory
40 #ver. 1.1.1: -Correct bug for real value of the High (bad error).
41 #             now it's less artistic, bat more real Always possible use 
42 #             the old formula. check Magnify (x4)
43 #            -Correct the bug for directory with dot in the name
44 #            -Add some warning and more information
45 #            -Add slider for the scale and info on it
46 #ver. 1.1.2: -Word correction
47 #            -Correct the problem for Unix (Upper lower case)
48 #              If the Ext of the file selected from user is upper
49 #              than the second file is Upper and Viceversa. 
50 #              (I can't verify because i have Win)
51 #ver. 1.1.3: -Little fix for previous fix on upper/lower case
52 #************************************************************************
53
54 import bpy 
55 import os.path
56 import math, array,  mathutils
57 from mathutils import *
58
59 TO_RAD=math.pi/180 #From degrees to radians
60
61 # turning off relative path - it causes an error if it was true
62 if bpy.context.user_preferences.filepaths.use_relative_paths == True:
63    bpy.context.user_preferences.filepaths.use_relative_paths = False
64    
65 # A very simple "bridge" tool.
66 # Connects two equally long vertex rows with faces.
67 # Returns a list of the new faces (list of  lists)
68 #
69 # vertIdx1 ... First vertex list (list of vertex indices).
70 # vertIdx2 ... Second vertex list (list of vertex indices).
71 # closed ... Creates a loop (first & last are closed).
72 # flipped ... Invert the normal of the face(s).
73 #
74 # Note: You can set vertIdx1 to a single vertex index to create a fan/star of faces.
75 # Note: If both vertex idx list are the same length they have to have at least 2 vertices.
76 def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
77     faces = []
78
79     if not vertIdx1 or not vertIdx2:
80         return None
81
82     if len(vertIdx1) < 2 and len(vertIdx2) < 2:
83         return None
84
85     fan = False
86     if (len(vertIdx1) != len(vertIdx2)):
87         if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
88             fan = True
89         else:
90             return None
91
92     total = len(vertIdx2)
93
94     if closed:
95         # Bridge the start with the end.
96         if flipped:
97             face = [
98                 vertIdx1[0],
99                 vertIdx2[0],
100                 vertIdx2[total - 1]]
101             if not fan:
102                 face.append(vertIdx1[total - 1])
103             faces.append(face)
104
105         else:
106             face = [vertIdx2[0], vertIdx1[0]]
107             if not fan:
108                 face.append(vertIdx1[total - 1])
109             face.append(vertIdx2[total - 1])
110             faces.append(face)
111
112     # Bridge the rest of the faces.
113     for num in range(total - 1):
114         if flipped:
115             if fan:
116                 face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
117             else:
118                 face = [vertIdx2[num], vertIdx1[num],
119                     vertIdx1[num + 1], vertIdx2[num + 1]]
120             faces.append(face)
121         else:
122             if fan:
123                 face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
124             else:
125                 face = [vertIdx1[num], vertIdx2[num],
126                     vertIdx2[num + 1], vertIdx1[num + 1]]
127             faces.append(face)
128     return faces
129     
130 #Utility Function ********************************************************
131 #
132 #Input: Latitude Output: Number of the line (1 to n)
133 def LatToLine(Latitude):
134     tmpLines=round((MAXIMUM_LATITUDE-Latitude)*MAP_RESOLUTION+1.0)
135     if tmpLines>LINES:tmpLines=LINES
136     return tmpLines
137         
138 #Input: Number of the line (1 to n) Output: Latitude 
139 def LineToLat(Line):
140     if MAP_RESOLUTION==0:
141         return 0
142     else:
143         return float(MAXIMUM_LATITUDE-(Line-1)/MAP_RESOLUTION)
144
145 #Input: Longitude Output: Number of the point (1 to n)
146 def LongToPoint(Longitude):
147     tmpPoints=round((Longitude-WESTERNMOST_LONGITUDE)*MAP_RESOLUTION+1.0)
148     if tmpPoints>LINE_SAMPLES:tmpPoints=LINE_SAMPLES
149     return tmpPoints
150
151 #Input: Number of the Point (1 to n) Output: Longitude
152 def PointToLong(Point):
153     if MAP_RESOLUTION==0:
154         return 0
155     else:
156             return float(WESTERNMOST_LONGITUDE+(Point-1)/MAP_RESOLUTION)
157
158 #Input: Latitude Output: Neareast real Latitude on grid
159 def RealLat(Latitude):
160         return float(LineToLat(LatToLine(Latitude)))
161
162 #Input: Longitude Output: Neareast real Longitude on grid       
163 def RealLong(Longitude):
164         return float(PointToLong(LongToPoint(Longitude)))
165 #**************************************************************************
166
167
168 #Read the LBL file    
169 def ReadLabel(FileName):
170     global FileAndPath
171     global LINES, LINE_SAMPLES, SAMPLE_TYPE, SAMPLE_BITS, UNIT, MAP_RESOLUTION, MAXIMUM_LATITUDE, MINIMUM_LATITUDE
172     global WESTERNMOST_LONGITUDE, EASTERNMOST_LONGITUDE, SCALING_FACTOR,OFFSET, RadiusUM, TARGET_NAME
173     global Message
174
175     if FileName=='':
176         LINES=LINE_SAMPLES=SAMPLE_BITS=MAP_RESOLUTION=0
177         MAXIMUM_LATITUDE=MINIMUM_LATITUDE=WESTERNMOST_LONGITUDE=EASTERNMOST_LONGITUDE=OFFSET=SCALING_FACTOR=0.0
178         SAMPLE_TYPE=UNIT=TARGET_NAME=RadiusUM=Message=""
179         return
180         
181     FileAndPath=FileName
182     FileAndExt=os.path.splitext(FileAndPath)
183     try:
184         #Check for UNIX that is case sensitive
185         #If the Ext of the file selected from user is Upper, than the second file is Upper and Viceversa
186         if FileAndExt[1].isupper(): 
187             f = open(FileAndExt[0] + ".LBL", 'r')  #Open the label file
188         else:
189             f = open(FileAndExt[0] + ".lbl", 'r')  #Open the label file
190         Message=""
191     except:
192         Message="FILE LBL NOT AVAILABLE OR YOU HAVEN'T SELECTED A FILE"
193         return
194     
195     block=""
196     OFFSET=0
197     for line in f:
198         tmp=line.split("=")
199         if tmp[0].strip()=="OBJECT" and tmp[1].strip()=="IMAGE":        
200             block="IMAGE"
201         elif tmp[0].strip()=="OBJECT" and tmp[1].strip()=="IMAGE_MAP_PROJECTION":       
202             block="IMAGE_MAP_PROJECTION"
203         elif tmp[0].strip()=="END_OBJECT" and tmp[1].strip()=="IMAGE":  
204             block=""
205         elif tmp[0].strip()=="END_OBJECT" and tmp[1].strip()=="IMAGE_MAP_PROJECTION":   
206             block=""
207         elif tmp[0].strip()=="TARGET_NAME":
208             block=""
209             TARGET_NAME=tmp[1].strip()
210         if block=="IMAGE":
211             if line.find("LINES") !=-1 and not(line.startswith("/*")):
212                 tmp=line.split("=")
213                 LINES=int(tmp[1].strip())
214             elif line.find("LINE_SAMPLES") != -1 and not(line.startswith("/*")):
215                 tmp=line.split("=")
216                 LINE_SAMPLES=int(tmp[1].strip())
217             elif line.find("UNIT") != -1 and not(line.startswith("/*")):
218                 tmp=line.split("=")
219                 UNIT=tmp[1].strip()
220             elif line.find("SAMPLE_TYPE") != -1 and not(line.startswith("/*")):
221                 tmp=line.split("=")
222                 SAMPLE_TYPE=tmp[1].strip()
223             elif line.find("SAMPLE_BITS") != -1 and not(line.startswith("/*")):
224                 tmp=line.split("=")
225                 SAMPLE_BITS=int(tmp[1].strip())
226             elif line.find("SCALING_FACTOR") != -1 and not(line.startswith("/*")):
227                 tmp=line.split("=")
228                 tmp=tmp[1].split("<")
229                 SCALING_FACTOR=float(tmp[0].replace(" ", ""))
230             elif line.find("OFFSET") != -1 and not(line.startswith("/*")):
231                 tmp=line.split("=")
232                 if tmp[0].find("OFFSET")!=-1 and len(tmp) > 1:
233                     tmp=tmp[1].split("<")
234                     tmp[0]=tmp[0].replace(".", "")
235                     OFFSET=float(tmp[0].replace(" ", ""))
236         elif block=="IMAGE_MAP_PROJECTION":
237             if line.find("A_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
238                 tmp=line.split("=")
239                 tmp=tmp[1].split("<")
240                 A_AXIS_RADIUS=float(tmp[0].replace(" ", ""))
241                 RadiusUM=tmp[1].rstrip().replace(">","")
242             elif line.find("B_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
243                 tmp=line.split("=")
244                 tmp=tmp[1].split("<")
245                 B_AXIS_RADIUS=float(tmp[0].replace(" ", ""))
246             elif line.find("C_AXIS_RADIUS") != -1 and not(line.startswith("/*")):
247                 tmp=line.split("=")
248                 tmp=tmp[1].split("<")
249                 C_AXIS_RADIUS=float(tmp[0].replace(" ", ""))
250             elif line.find("MAXIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
251                 tmp=line.split("=")
252                 tmp=tmp[1].split("<")
253                 MAXIMUM_LATITUDE=float(tmp[0].replace(" ", ""))
254             elif line.find("MINIMUM_LATITUDE") != -1 and not(line.startswith("/*")):
255                 tmp=line.split("=")
256                 tmp=tmp[1].split("<")
257                 MINIMUM_LATITUDE=float(tmp[0].replace(" ", ""))
258             elif line.find("WESTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
259                 tmp=line.split("=")
260                 tmp=tmp[1].split("<")
261                 WESTERNMOST_LONGITUDE=float(tmp[0].replace(" ", ""))
262             elif line.find("EASTERNMOST_LONGITUDE") != -1 and not(line.startswith("/*")):
263                 tmp=line.split("=")
264                 tmp=tmp[1].split("<")
265                 EASTERNMOST_LONGITUDE=float(tmp[0].replace(" ", ""))
266             elif line.find("MAP_RESOLUTION") != -1 and not(line.startswith("/*")):
267                 tmp=line.split("=")
268                 tmp=tmp[1].split("<")
269                 MAP_RESOLUTION=float(tmp[0].replace(" ", ""))
270     f.close
271     MAXIMUM_LATITUDE=MAXIMUM_LATITUDE-1/MAP_RESOLUTION/2
272     MINIMUM_LATITUDE=MINIMUM_LATITUDE+1/MAP_RESOLUTION/2
273     WESTERNMOST_LONGITUDE=WESTERNMOST_LONGITUDE+1/MAP_RESOLUTION/2
274     EASTERNMOST_LONGITUDE=EASTERNMOST_LONGITUDE-1/MAP_RESOLUTION/2
275     if OFFSET==0: #When OFFSET isn't available I use the medium of the radius
276         OFFSET=(A_AXIS_RADIUS+B_AXIS_RADIUS+C_AXIS_RADIUS)/3
277     else:
278         OFFSET=OFFSET/1000 #Convert m to Km
279     if SCALING_FACTOR==0: SCALING_FACTOR=1.0 #When isn'tavailable I set it to 1
280
281 def MakeMaterialMars(obj):
282     #Copied from io_convert_image_to_mesh_img
283     mat = bpy.data.materials.new("Mars")
284     mat.diffuse_shader = 'MINNAERT'
285     mat.diffuse_color=(0.426, 0.213, 0.136)
286     mat.darkness=0.8
287     
288     mat.specular_shader = 'WARDISO'
289     mat.specular_color= (1.000, 0.242, 0.010) 
290     mat.specular_intensity=0.010 
291     mat.specular_slope= 0.100
292     obj.data.materials.append(mat)
293
294 def MakeMaterialMoon(obj):
295     #Same as Mars Material, but i have canged the color
296     mat = bpy.data.materials.new("Moon")
297     mat.diffuse_shader = 'MINNAERT'
298     mat.diffuse_color=(0.426, 0.426, 0.426)
299     mat.darkness=0.8
300     
301     mat.specular_shader = 'WARDISO'
302     mat.specular_color= (0.6, 0.6, 0.6) 
303     mat.specular_intensity=0.010 
304     mat.specular_slope= 0.100
305     obj.data.materials.append(mat)
306     
307 def clear_properties():
308     # can happen on reload
309     if bpy.context.scene is None:
310         return
311
312     LINES=LINE_SAMPLES=SAMPLE_BITS=0
313     MAXIMUM_LATITUDE=MINIMUM_LATITUDE=WESTERNMOST_LONGITUDE=EASTERNMOST_LONGITUDE=OFFSET=SCALING_FACTOR=MAP_RESOLUTION=0.0
314     SAMPLE_TYPE=UNIT=TARGET_NAME=RadiusUM=Message=""
315         
316     props = ["FromLat", "ToLat", "FromLong", "ToLong", "Scale"]
317     for p in props:
318         if p in bpy.types.Scene.bl_rna.properties:
319             exec("del bpy.types.Scene."+p)
320         if p in bpy.context.scene:
321             del bpy.context.scene[p]
322             
323 #Import the data and draw the planet  
324 class Import(bpy.types.Operator):
325     bl_idname = 'Import'
326     bl_label = 'Start Import'
327     bl_description = 'Import the data'
328
329     def execute(self, context):
330         From_Lat=RealLat(bpy.context.scene['FromLat'])
331         To_Lat=RealLat(bpy.context.scene['ToLat'])
332         From_Long=RealLong(bpy.context.scene['FromLong'])
333         To_Long=RealLong(bpy.context.scene['ToLong'])
334         BlenderScale=bpy.context.scene['Scale']
335         Exag=bpy.context.scene['Exaggerate']
336         Vertex=[] #Vertex array
337         Faces=[]  #Faces arrays
338         FirstRow=[]
339         SecondRow=[]
340         print('*** Start create vertex ***')
341         FileAndPath=bpy.context.scene['fpath']
342         FileAndExt=os.path.splitext(FileAndPath)
343         #Check for UNIX that is case sensitive
344         #If the Ext of the file selected from user is Upper, than the second file is Upper and Viceversa
345         if FileAndExt[1].isupper(): 
346             FileName=FileAndExt[0] + ".IMG"
347             print("Upper")
348         else:
349             FileName=FileAndExt[0] + ".img"
350             print("Lower")
351         f=open(FileName,'rb')
352         f.seek(int((int(LatToLine(From_Lat))-1)*(LINE_SAMPLES*(SAMPLE_BITS/8))),1)#Skip the first n line of point
353         SkipFirstPoint=int((LongToPoint(From_Long)-1)*(SAMPLE_BITS/8)) #Nunmber of points to skip
354         PointsToRead=(LongToPoint(To_Long)-LongToPoint(From_Long)+1)*(int(SAMPLE_BITS)/8) #Number of points to be read
355         SkipLastPoint=(LINE_SAMPLES*(SAMPLE_BITS/8))-PointsToRead-SkipFirstPoint #Nunmber of points to skip
356         LatToRead=From_Lat
357         while (LatToRead>=To_Lat):
358             f.seek(SkipFirstPoint,1) #Skip the first n point
359             Altitudes=f.read(int(PointsToRead)) #Read all the point
360             Altitudes=array.array("h",Altitudes) #Change to Array of signed short
361             if SAMPLE_TYPE=="MSB_INTEGER":
362                 Altitudes.byteswap() #Change from MSB (big endian) to LSB (little endian)
363             LongToRead=From_Long
364             PointToRead=0
365             while (LongToRead<=To_Long):
366                 if Exag:
367                     tmpRadius=(Altitudes[PointToRead]/SCALING_FACTOR/1000+OFFSET)/BlenderScale #Old formula (High*4)
368                 else:
369                     tmpRadius=((Altitudes[PointToRead]*SCALING_FACTOR)/1000+OFFSET)/BlenderScale #Correct scale
370                 CurrentRadius=tmpRadius*(math.cos(LatToRead*TO_RAD))
371                 X=CurrentRadius*(math.sin(LongToRead*TO_RAD))
372                 Y=tmpRadius*math.sin(LatToRead*TO_RAD)
373                 Z=CurrentRadius*math.cos(LongToRead*TO_RAD)
374                 Vertex.append(Vector((float(X),float(Y),float(Z))))
375                 LongToRead+=(1/MAP_RESOLUTION)
376                 PointToRead+=1
377             f.seek(int(SkipLastPoint),1)        
378             LatToRead-=(1/MAP_RESOLUTION)
379         f.close
380         del Altitudes
381         print('*** End create Vertex   ***')
382
383         print('*** Start create faces ***')
384         LinesToRead=int(LatToLine(To_Lat)-LatToLine(From_Lat)+1)   #Number of the lines to read
385         PointsToRead=int(LongToPoint(To_Long)-LongToPoint(From_Long)+1) #Number of the points to read
386         for Point in range(0,PointsToRead):
387             FirstRow.append(Point)
388             SecondRow.append(Point+PointsToRead)
389         if int(PointsToRead)==LINE_SAMPLES:
390             FaceTemp=createFaces(FirstRow,SecondRow,closed=True,flipped=True)
391         else:
392             FaceTemp=createFaces(FirstRow,SecondRow,closed=False,flipped=True)
393         Faces.extend(FaceTemp)
394         
395         FaceTemp=[]
396         for Line in range(1,(LinesToRead-1)):
397             FirstRow=SecondRow
398             SecondRow=[] 
399             FacesTemp=[]
400             for Point in range(0,PointsToRead):
401                 SecondRow.append(Point+(Line+1)*PointsToRead)
402             if int(PointsToRead)==LINE_SAMPLES:
403                 FaceTemp=createFaces(FirstRow,SecondRow,closed=True,flipped=True)
404             else:
405                 FaceTemp=createFaces(FirstRow,SecondRow,closed=False,flipped=True)
406             Faces.extend(FaceTemp)
407         del FaceTemp
408         print('*** End create faces   ***')
409
410         print ('*** Start draw ***')        
411         mesh = bpy.data.meshes.new(TARGET_NAME)
412         mesh.from_pydata(Vertex, [], Faces)
413         del Faces
414         del Vertex
415         mesh.update()
416         ob_new = bpy.data.objects.new(TARGET_NAME, mesh)
417         ob_new.data = mesh
418         scene = bpy.context.scene
419         scene.objects.link(ob_new)
420         scene.objects.active = ob_new
421         ob_new.select = True
422         print ('*** End draw   ***')        
423         print('*** Start Smooth ***')
424         bpy.ops.object.shade_smooth()
425         print('*** End Smooth   ***')
426         if TARGET_NAME=="MOON":
427             MakeMaterialMoon(ob_new)
428         elif TARGET_NAME=="MARS":
429             MakeMaterialMars(ob_new)
430         print('*** FINISHED ***')
431         return {'FINISHED'}
432         
433 # drawing the user interface
434 class Img_Importer(bpy.types.Panel):
435     bl_space_type = "VIEW_3D"
436     bl_region_type = "TOOL_PROPS"
437     bl_label = "LRO Lola & MGS Mola IMG Importer"
438
439     def __init__(self, context):
440         LINES=LINE_SAMPLES=SAMPLE_BITS=MAP_RESOLUTION=0
441         MAXIMUM_LATITUDE=MINIMUM_LATITUDE=WESTERNMOST_LONGITUDE=EASTERNMOST_LONGITUDE=OFFSET=SCALING_FACTOR=0.0
442         SAMPLE_TYPE=UNIT=TARGET_NAME=RadiusUM=Message=""
443
444         # intializing variables
445         props = [("FromLat",0.0),("ToLat",0.0),("FromLong",0.0),("ToLong",0.0),("Scale",1),("Exaggerate",False)]
446         for p, num in props:
447             if not p in bpy.context.scene.keys():
448                 bpy.context.scene[p] = num
449
450     def draw(self, context):
451         obj = context.object
452         typ = bpy.types.Scene
453         var = bpy.props
454         typ.fpath = var.StringProperty(name="Import File ", description="Select your img file", subtype="FILE_PATH", default="")
455         
456         ReadLabel(bpy.context.scene.fpath)
457         
458         typ.FromLat=var.FloatProperty(description="From Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE),precision=3)
459         typ.ToLat=var.FloatProperty(description="To Latitude", min=float(MINIMUM_LATITUDE), max=float(MAXIMUM_LATITUDE),precision=3)
460         typ.FromLong=var.FloatProperty(description="From Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE),precision=3)
461         typ.ToLong=var.FloatProperty(description="To Longitude", min=float(WESTERNMOST_LONGITUDE), max=float(EASTERNMOST_LONGITUDE),precision=3)
462         typ.Scale=var.IntProperty(description="Scale", min=1, max=100,default=1)
463         typ.Exaggerate=var.BoolProperty(description="Magnify", default=False)
464
465         layout = self.layout
466         layout.prop(context.scene, "fpath")
467         
468         col = layout.column()
469         split = col.split(align=True)
470         split.label("Minimum Latitude: "+str(MINIMUM_LATITUDE)+" deg")
471         split.label("Maximum Latitude: "+str(MAXIMUM_LATITUDE)+" deg")
472         
473         split = col.split(align=True)
474         split.label("Westernmost Longitude: "+str(WESTERNMOST_LONGITUDE)+" deg")
475         split.label("Easternmost Longitude: "+str(EASTERNMOST_LONGITUDE)+" deg")        
476
477         split = col.split(align=True)
478         split.label("Lines: " + str(LINES))
479         split.label("Line samples: " + str(LINE_SAMPLES))
480         
481         split = col.split(align=True)
482         split.label("Sample type: "+str(SAMPLE_TYPE))
483         split.label("Sample bits: "+str(SAMPLE_BITS))
484
485         split = col.split(align=True)
486         split.label("Unit: "+UNIT)
487         split.label("Map resolution: "+str(MAP_RESOLUTION) + " pix/deg")
488         
489         split = col.split(align=True)
490         split.label("Radius: "+str(OFFSET)+ " " + RadiusUM)
491         split.label("Scale: "+str(SCALING_FACTOR))
492         
493         split = col.split(align=True)
494         split.label("Target: ")
495         split.label(TARGET_NAME)
496                 
497         col = layout.column()
498         split = col.split(align=True)
499         split.prop(context.scene, "FromLat", "Northernmost Lat.")
500         split.prop(context.scene, "ToLat", "Southernmost Lat.")
501         if bpy.context.scene['FromLat'] < bpy.context.scene['ToLat']:
502             col = layout.column()
503             split = col.split(align=True)
504             split.label("Warning: Northernmost must be greater than Southernmost")
505         
506         col = layout.column()
507         split = col.split(align=True)
508         split.prop(context.scene, "FromLong", "Westernmost Long.")
509         split.prop(context.scene, "ToLong", "Easternmost Long.")
510         if bpy.context.scene['FromLong'] > bpy.context.scene['ToLong']:
511             col = layout.column()
512             split = col.split(align=True)
513             split.label("Warning: Easternmost must be greater than Westernmost")
514         
515         col = layout.column()
516         split = col.split(align=True)
517         split.prop(context.scene, "Scale", "Scale")
518         split.prop(context.scene, "Exaggerate", "Magnify (x4)")
519         if bpy.context.scene.fpath !="":
520             col = layout.column()
521             split = col.split(align=True)
522             split.label("1 Blender unit = " + str(bpy.context.scene['Scale']) +RadiusUM)  
523             
524         if Message!="":
525             col = layout.column()
526             split = col.split(align=True)
527             split.label("Message: " + Message)
528         
529         if bpy.context.scene.fpath.upper().endswith("IMG") or bpy.context.scene.fpath.upper().endswith("LBL"): #Check if is selected the correct file
530             VertNumbers=(((RealLat(bpy.context.scene['FromLat'])-RealLat(bpy.context.scene['ToLat']))*MAP_RESOLUTION)+1)*((RealLong(bpy.context.scene['ToLong'])-RealLong(bpy.context.scene['FromLong']))*MAP_RESOLUTION+1)
531         else:
532             VertNumbers=0
533         #If I have 4 or plus vertex and at least 2 row and at least 2 point, I can import
534         if VertNumbers>3 and (RealLat(bpy.context.scene['FromLat'])> RealLat(bpy.context.scene['ToLat'])) and (RealLong(bpy.context.scene['FromLong'])<RealLong(bpy.context.scene['ToLong'])): #If I have 4 or plus vertex I can import
535             split = col.split(align=True)
536             split.label("Map resolution on the equator: ")
537             split.label(str(2*math.pi*OFFSET/360/MAP_RESOLUTION) + " " + RadiusUM + "/pix")
538             col = layout.column()
539             split = col.split(align=True)
540             split.label("Real Northernmost Lat.: " + str(RealLat(bpy.context.scene['FromLat']))+" deg")
541             split.label("Real Southernmost Long.: " + str(RealLat(bpy.context.scene['ToLat']))+" deg")
542             split = col.split(align=True)
543             split.label("Real Westernmost Long.: " + str(RealLong(bpy.context.scene['FromLong']))+" deg")
544             split.label("Real Easternmost Long.: " + str(RealLong(bpy.context.scene['ToLong']))+"deg")
545             split = col.split(align=True)
546             VertNumbers=(((RealLat(bpy.context.scene['FromLat'])-RealLat(bpy.context.scene['ToLat']))*MAP_RESOLUTION)+1)*((RealLong(bpy.context.scene['ToLong'])-RealLong(bpy.context.scene['FromLong']))*MAP_RESOLUTION+1)
547             split.label("Numbers of vertex to be imported: "+ str(int(VertNumbers)))
548             col.separator()
549             col.operator('Import', text='Import')
550     
551 # registering the script
552 def register():
553     pass
554
555 def unregister():
556     clear_properties()
557
558 if __name__ == "__main__":
559     register()