I would like to write code for creating a thematic map.
The GUI command in Mapbasic window shows many lines in order to set up the different colours which will be used on the different polygons (i.e. Brush (2, 16760, 2300)).
Is it possible to generate this part automatically provided the user gives some parameters ?
Part of the code would look like the following:
Declare Sub Main()
Declare Sub sThematic
Sub Main()
Call sThematic
End Sub
Dim nStep As Integer
Dim sSymbole As Brush
Dim sSymbol(300) As Float
Dim counter As Integer
Dim sTableName As String
Dim sDataCol As Integer
Dim nBreak As String
Dim sStatement As String
Dim sStatementStart As String
Dim sStatementMid As String
Dim sStatementEnd As String
SUB sThematic
sSymbol(1) = MakeBrush (49, 12632256, 12)
sSymbol(2) = MakeBrush ("+sDefaultSymbol+", 16752895, 8)
sSymbol(3) = MakeBrush ("+sDefaultSymbol+", 9445631, 8)
sSymbol(4) = MakeBrush ("+sDefaultSymbol+", 255, 8)
sSymbol(5) = MakeBrush ("+sDefaultSymbol+", 65280, 12)
sSymbol(6) = MakeBrush ("+sDefaultSymbol+", 16776960, 12)
sSymbol(7) = MakeBrush ("+sDefaultSymbol+", 16744448, 12)
sSymbol(8) = MakeBrush ("+sDefaultSymbol+", 16711680, 12)
sStatementStart = "shade window " + winID + " " + sTableName + " with " + sDataCol + " ranges apply all use all Symbol (49,12632256,12) "
sStatementMid = ""
sStatementEnd = " default Brush (2,8421504,16777215) # use 2 round 1 inflect off Symbol (0,0,0) at 5 by 0 color 1 #"
nStep = 8
For counter = 1 to nStep
sStatementMid = sStatementMid + nBreak(counter) + ": " + nBreak(counter + 1) + sSymbol(counter)
Next
sStatement = sStatementStart + sStatementMid + sStatementEnd
Run Command sStatement
End Sub
-
Not sure if I understand your question. I assume the code above works, right? If you are looking ofr a way to create a number of styles, have a look at the Create Styles statementPeter Horsbøll Møller– Peter Horsbøll Møller2014年05月05日 08:36:00 +00:00Commented May 5, 2014 at 8:36
-
Thank you for your response. The above code compiles but does not run. I just put it as an example for what I am looking for. What I would like to do is basically automate the "shade window" command in creating a thematic map (taking into account a specific variable which takes on various colors as its value changes).user3405572– user34055722014年05月06日 13:32:03 +00:00Commented May 6, 2014 at 13:32
1 Answer 1
I don't know how wedded you are to the idea of doing what you want to do in MapBasic, but frankly that would be my approach of last resort.
If you know what styles you want to apply (conditional on values of a data table column), you're better off writing a script (in, e.g., a useful language like Python) to create metadata: then you can store it and append it to any TAB file for which it's appropriate. NOTE: This only applies to MapInfo 12.5+ as far as I can establish: in order versions, the metadata is ignored (this is true for MapInfo 8 and 10).
We have a bunch of 'standard' thematic style-sets that get applied repeatedly - so I have an 'include' file that contains the metadata in the format MapInfo requires (as opposed to something XML-ish).
The one we use for Residential Land Supply has 6 categories that depend on a column called 'Timing', which can take the values
- 'New Inclusion'
- '1-2years'
- '3-5years'
- '6-10years'
- '11+years' or
- 'No Timing'.
The metadata required for this structure looks like this (note you have to use MapInfo colour codes):
begin_metadata
"\DefaultTheme" = ""
"\DefaultTheme\Expression" = "Timing"
"\DefaultTheme\Expression\IsSimpleCol" = "1"
"\DefaultTheme\ThemeType" = "5"
"\DefaultTheme\Bins" = ""
"\DefaultTheme\Bins\Count" = "6"
"\DefaultTheme\Bins\Bin" = ""
"\DefaultTheme\Bins\Bin1円" = ""
"\DefaultTheme\Bins\Bin1円\From" = """1-2years"""
"\DefaultTheme\Bins\Bin1円\BinBrush" = "Brush (2,8760080,16777215) "
"\DefaultTheme\Bins\Bin1円\BinBorderPen" = "Pen (1,1,0) "
"\DefaultTheme\Bins\Bin2円" = ""
"\DefaultTheme\Bins\Bin2円\From" = """11+years"""
"\DefaultTheme\Bins\Bin2円\BinBrush" = "Brush (2,16777104,16777215) "
"\DefaultTheme\Bins\Bin2円\BinBorderPen" = "Pen (1,1,0) "
"\DefaultTheme\Bins\Bin3円" = ""
"\DefaultTheme\Bins\Bin3円\From" = """3-5years"""
"\DefaultTheme\Bins\Bin3円\BinBrush" = "Brush (2,13099858,16777215) "
"\DefaultTheme\Bins\Bin3円\BinBorderPen" = "Pen (1,1,0) "
"\DefaultTheme\Bins\Bin4円" = ""
"\DefaultTheme\Bins\Bin4円\From" = """6-10years"""
"\DefaultTheme\Bins\Bin4円\BinBrush" = "Brush (2,14346396,16777215) "
"\DefaultTheme\Bins\Bin4円\BinBorderPen" = "Pen (1,1,0) "
"\DefaultTheme\Bins\Bin5円" = ""
"\DefaultTheme\Bins\Bin5円\From" = """New Inclusion"""
"\DefaultTheme\Bins\Bin5円\BinBrush" = "Brush (8,8760080,16777215) "
"\DefaultTheme\Bins\Bin5円\BinBorderPen" = "Pen (1,2,8760080) "
"\DefaultTheme\Bins\Bin6円" = ""
"\DefaultTheme\Bins\Bin6円\From" = """No Timing"""
"\DefaultTheme\Bins\Bin6円\BinBrush" = "Brush (1,65535,16777215) "
"\DefaultTheme\Bins\Bin6円\BinBorderPen" = "Pen (1,2,16711680) "
"\DefaultTheme\Apply" = "15"
"\DefaultTheme\DefaultBrush" = "Brush (1,0,16777215) "
"\DefaultTheme\DefaultBorderPen" = "Pen (1,2,0) "
end_metadata
That works well, and takes five seconds to insert into the TAB file (obviously it's useless if the file does not have a 'Timing' column). As you can see, the structure is pretty straightforward.
So if the data I'm dealing with is a Residential Land Supply data structure, and some counterparty simply must have the output in MapInfo, I append that metadata to the bottom of the TAB file - using a [Python] script rather than pfaffing around in MapInfo or MapBasic. When the other person opens the file, it is themed.
If you don't know the table structure or the appropriate data ranges to use to classify your data, you can get it by querying the data table using ogr2ogr (better yet, use ogr2ogr to import the data into PostgreSQL, then do everything in QGIS: replicable XML-style themes are so easy).
If you don't know the colour ramp that you would like, colorbrewer can be useful - and there are resources like tydac's color calculator that enable translation between MapInfo's ludicrous internal colour kludge and RGBA or hex-codes. (MapInfo's colour is X = (red * 65536) + (green * 256) + blue
; you can get back to hex colour codes by hex() in python, then replacing the leading 0x
by #
. MapInfo codes for pen & fill styles is here.