polygon color to field

151 views
Skip to first unread message

Thoern

unread,
Dec 28, 2011, 7:57:05 AM12/28/11
to MapInfo-L
I wonder if one can extract a regions color and save the color to a
column value (Hexadec form)
Tried to grab the color of a selected polygon as below, but it says
"OBJ_INFO_BRUSH is not defined"

dim b_fillstyle = ObjectInfo(Selection.obj, OBJ_INFO_BRUSH) note
b_fillstyle

Thomas Bacon

unread,
Dec 28, 2011, 8:59:40 AM12/28/11
to mapi...@googlegroups.com
You need to include the mapbasic definitions file at the top of your
code:

Include "MapBasic.def"

OR

Use the integer value defined in the definitions file:

dim b_fillstyle = ObjectInfo(Selection.obj,3)

HTH,

Tom Bacon
Graduate GIS Engineer
Asset Management South
Tel: 01444 472380
www.mouchel.com

--
You received this message because you are subscribed to the
Google Groups "MapInfo-L" group.To post a message to this group, send
email to mapi...@googlegroups.com
To unsubscribe from this group, go to:
http://groups.google.com/group/mapinfo-l/subscribe?hl=en
For more options, information and links to MapInfo resources (searching
archives, feature requests, to visit our Wiki, visit the Welcome page at
http://groups.google.com/group/mapinfo-l?hl=en


The information in this e-mail is confidential and may be legally privileged. It is intended solely for the addressee. Access to this email by anyone else is unauthorised. Any views or opinions expressed in this e-mail may be solely those of the author and are not necessarily those of Mouchel. Mouchel Limited, Registered in England at Export House, Cawsey Way, Woking, Surrey, UK, GU21 6QX Registered No : 1686040

Thoern

unread,
Jan 9, 2012, 10:34:50 AM1/9/12
to MapInfo-L
Aha ok, any good ideas how to convert the result to hexadecimal color
codes?

Brush (2, 16711680, 16777215)


Bill Thoen

unread,
Jan 9, 2012, 12:01:02 PM1/9/12
to mapi...@googlegroups.com
nRed = nColor \ &H10000
nGreen = nColor \ &H100 mod &H100
nBlue = nColor mod &H100

This gives you the individual colors (should you need them).
Then your next step is to convert decimal numbers to hexadecimal alphanumeric. The basic technique is to first build a function to convert a number in the 0 - 255 range into hex, step through the number column by column, converting each power of 256 into it's hexadecimal exquivalent. And believe it or not, it's easier to work in hexadecimal notation that decimal.

Function toHexByte( byval decByte as smallint ) as string
Dim hexByte as string, nybble(2) as smallint
If decByte > &h100 then
Print "value out of range 0 - 255"
Exit function
End if

nybble(2) = decByte \ &h10
nybble(1) = decByte mod &h10
For i = 1 to 2
hexByte = hexByte
+ mid$( "0123456789ABCDEF", nybble(i) , 1 )
Next
toHexByte = hexByte
End function
' Now split the color value into byte-size chunks (as shown above ) and stick them together.

nRed = nColor \ &H10000
nGreen = nColor \ &H100 mod &H100
nBlue = nColor mod &H100

sHex = toHexByte( nRed )
+ toHexByte( nGreen )
+ toHexByte( nBlue )

That should do it! (However, I'm not able to check it where I am just now, so if something doesn't work, please let me know and I'll fix it.) if you want to tighten up that last loop, use an array for nRed, nGreen and nBlue, then you can loop through the color bands and output all in one step.

Integer divide '\' and 'Mod' are pretty useful operators in some situations, because all we're really doing here is shifting and masking bits, which is what they do ( or at least when you use them only with powers of two. )

Regards,

Bill Thoen
GISnet
http://gisnet.com
303-786-9961

Thoern

unread,
Jan 19, 2012, 7:27:04 AM1/19/12
to MapInfo-L
Hi Bill thanks for your input.
I dont think I got it completely though.
Maby things goes baserk becauce of not being in the form of RGB?

When calling a completely blue polygon with:

ObjectInfo(Selection.obj,3)

I get: Brush (2, 255, 16777215)
Not sure what color and form the 16777215 value is??


Tried to first isolate the three numbers inisde of the clamps.
Then splitting up the string into 3 nRed,nGreen,nBlue

Then the function toHexByte



GLOBAL nRed as float
GLOBAL nGreen as float
GLOBAL nBlue as float
GLOBAL sHex as string
GLOBAL nColor as string


SUB MAIN

nColor = ObjectInfo(Selection.obj,3)
'Brush (2, 16711680, 16777215)
nColor=right$(nColor, len(nColor)-7)
nColor=left$(nColor, len(nColor)-1)

print ncolor
nRed = Left$(nColor, InStr(1, nColor, ",")-1)
nGreen = Mid$(nColor, InStr(1, nColor, ",")+1,InStr(InStr(1, nColor,
",")+1, nColor, ",")-InStr(1, nColor, ",")-1)
nBlue = Mid$(nColor, InStr(InStr(1, nColor, ",")+1, nColor, ",")+1,
Len(nColor))
note nred
note nGreen
note nBlue

nRed = nRed \ &H10000
nGreen = nGreen \ &H100 mod &H100
nBlue = nBlue mod &H100

sHex = toHexByte( nRed )
+ toHexByte( nGreen )
+ toHexByte( nBlue )
note sHex
End sub

Function toHexByte( byval decByte as smallint ) as string
Dim hexByte as string, nybble(2) as smallint,i as integer
If decByte > &h100 then
note "value out of range 0 - 255"

KTG Infotech

unread,
Jan 19, 2012, 9:58:21 AM1/19/12
to mapi...@googlegroups.com
Discover does the work for you..if you have it try..it does wonders

--
You received this message because you are subscribed to the
Google Groups "MapInfo-L" group.To post a message to this group, send
email to mapi...@googlegroups.com
To unsubscribe from this group, go to:
http://groups.google.com/group/mapinfo-l/subscribe?hl=en
For more options, information and links to MapInfo resources (searching
archives, feature requests, to visit our Wiki, visit the Welcome page at
http://groups.google.com/group/mapinfo-l?hl=en



--
Kalai Selvan
KTG Infotech
CAD/GIS/Geo spatial Services
Skypes- ktgcad


Bill Thoen

unread,
Jan 19, 2012, 11:32:57 AM1/19/12
to mapi...@googlegroups.com
16777215 is the base10 number for white. In your example, it's the background color for the brush. In base256 ( where the colors live ) that number would be &HFFFFFF, which equals
255*256^2 + 255*256^1 + 255*256^0
It's just like our familiar decimal system, except that each column in a color number can range from 0 to 255 instead of 0 to 9.

Just as the decimal number 16777215 is really 1*10^7 + 6*10^6 + 7*10^5 +7*10^4 +7*10^3 + 2*10^2 + 1*10^1 + 5*10^0, the same rules apply in other bases, even binary, e.g. b0110 = 0*2^3 + 1*2^2 + 1*2^1 + 0*2^0 = 6

It's not an easy topic to understand, but once you do get it, a lot "computer math" makes a lot more sense, and it's much easier to work in hexadecimal notation! But just as you did when you were learning numbers in the first grade, you have memorize the notation and the order of the digits and just start thinkingrqa in chunks of 256 or when you really get it, chunks of &H100.

On Jan 19, 2012, at 5:27 AM, Thoern <turbo...@hotmail.com>*wrote

ssim...@baltometro.org

unread,
Jan 19, 2012, 1:22:56 PM1/19/12
to mapi...@googlegroups.com
The *really important* thing to learn here is to use StyleAttr() to get
information out of a style, rather than all that string manipulation.

Include "mapbasic.def"

dim b as brush
dim ipat as integer
dim ifclr as integer
dim ibclr as integer
dim ired as smallint
dim iblue as smallint
dim igreen as smallint

b = ObjectInfo(Selection.obj,3)

' BRUSH_PATTERN is 2, meaning SOLID
ipat = StyleAttr (b, BRUSH_PATTERN)

' BRUSH_FORECOLOR is 255
ifclr = StyleAttr (b, BRUSH_FORECOLOR)

' BRUSH_BACKCOLOR is 16777215, but it's meaningless because of the solid
pattern
ibclr = StyleAttr (b, BRUSH_BACKCOLOR)

ired = ifclr \ &H10000 ' value is 0
igreen = ifclr \ &H100 mod &H100 ' value is also 0
iblue = ifclr mod &H100 ' value is 255

Spencer

ObjectInfo(Selection.obj,3)

Then the function toHexByte


SUB MAIN

--

Thoern

unread,
Feb 10, 2012, 8:14:30 AM2/10/12
to MapInfo-L
Hello there sorry for naging about this :-)
I am not sure what I am suppose to feed that function with? I end up
with something else than hex color :-|
I run this mbx below while haveing a selected polygon in a map.
I ended up doing a really slow working vb.net dll that does the same
(vb.net has hex function built in)..
But it would be nice to have this working in thrue Mapbasic.




GLOBAL nColor as integer


Sub main

Dim b as brush
b = ObjectInfo(Selection.obj,3)
nColor = StyleAttr (b, BRUSH_FORECOLOR)


nRed = nColor \ &H10000
nGreen = nColor \ &H100 mod &H100
nBlue = nColor mod &H100

sHex = toHexByte( nRed )
+ toHexByte( nGreen )
+ toHexByte( nBlue )


Note sHex

End sub



Function toHexByte( byval decByte as smallint ) as string
Dim hexByte as string, nybble(2) as smallint
If decByte > &h100 then
Print "value out of range 0 - 255"
Exit function
End if

nybble(2) = decByte \ &h10
nybble(1) = decByte mod &h10
For i = 1 to 2
hexByte = hexByte
+ mid$( "0123456789ABCDEF", nybble(i) , 1 )
Next
toHexByte = hexByte
End function




























On 9 Jan, 18:01, Bill Thoen <bth...@gisnet.com> wrote:
> nRed = nColor \ &H10000
> nGreen = nColor \ &H100 mod &H100
> nBlue = nColor  mod &H100
>
> This gives you the individual colors (should you need them).
> Then your next step is to convert decimal numbers to hexadecimal alphanumeric. The basic technique is to first build a function to convert a number in the 0 - 255 range intohex, step through the number column by column, converting each power of 256 into it's hexadecimal exquivalent. And believe it or not, it's easier to work in hexadecimal notation that decimal.
>
> Function toHexByte( byval decByte as smallint ) as string
> Dim hexByte as string, nybble(2) as smallint
>      If decByte > &h100 then
>           Print "value out of range 0 - 255"
>           Exit function
>      End if
>
>     nybble(2) = decByte \ &h10
>     nybble(1) = decByte mod &h10
>     For i = 1 to 2
>        hexByte = hexByte
>             + mid$( "0123456789ABCDEF", nybble(i) , 1 )
>     Next
>         toHexByte = hexByte
> End function
> ' Now split thecolorvalue into byte-size chunks (as shown above ) and stick them together.
>
> nRed = nColor \ &H10000
> nGreen = nColor \ &H100 mod &H100
> nBlue = nColor  mod &H100
>
> sHex = toHexByte( nRed )
>          + toHexByte( nGreen )
>          + toHexByte( nBlue )
>
> That should do it! (However, I'm not able to check it where I am just now, so if something doesn't work, please let me know and I'll fix it.) if you want to tighten up that last loop, use an array for nRed, nGreen and nBlue, then you can loop through thecolorbands and output all in one step.
>
> Integer divide '\' and 'Mod' are pretty useful operators in some situations, because all we're really doing here is shifting and masking bits, which is what they do ( or at least when you use them only with powers of two. )
>
> Regards,
>
> Bill Thoen
> GISnethttp://gisnet.com
> 303-786-9961

Spencer Simpson

unread,
Feb 10, 2012, 9:54:27 AM2/10/12
to mapi...@googlegroups.com
Notice that your code doesn't declare sHex anywhere (but it *is* a string).
If you haven't added this somewhere:

dim sHex as string

there's probably some sort of silent conversion going on.

Spencer

-----Original Message-----
From: Thoern [mailto:turbo...@hotmail.com]
Sent: Friday, February 10, 2012 8:15 AM
To: MapInfo-L
Subject: [MI-L] Re: polygon color to field

Thoern

unread,
Feb 13, 2012, 2:22:10 AM2/13/12
to MapInfo-L
Yes the original had a dim sex as string :-)

Thoern

unread,
Feb 13, 2012, 5:17:23 AM2/13/12
to MapInfo-L
It seems the function is working like below and gives Hex color from
selected decimal color value.
By removing the 0 replacement string, and setting a condition if the
r,g,b value is shorter than 3 digits.. not sure why but there is some
strange error somewhere...





SUB MAIN


dim b as brush
dim hRed,hGreen,hBlue as string
b = ObjectInfo(Selection.obj,3)
nColor = StyleAttr (b, BRUSH_FORECOLOR)


nRed = nColor \ &H10000
nGreen = nColor \ &H100 mod &H100
nBlue = nColor mod &H100


hRed=toHexByte(nRed)
hGreen=toHexByte(nGreen)
hBlue=toHexByte(nBlue)

If Len(hRed) < 2 Then hRed = hRed & "0" End if
If Len(hGreen) < 2 Then hGreen = hGreen & "0" End if
If Len(hBlue) < 2 Then hBlue = hBlue & "0" End if

sHex = (hRed & hGreen & hBlue)

note sHex
End sub


Function toHexByte( byval decByte as smallint ) as string
Dim hexByte as string, nybble(2) as smallint
dim i as integer
If decByte > &h100 then
Print "value out of range 0 - 255"
Exit function
End if

nybble(2) = decByte \ &h10
nybble(1) = decByte mod &h10
For i = 1 to UBound(nybble)
hexByte = hexByte
+ mid$( "123456789ABCDEF", nybble(i) , 1)

Spencer Simpson

unread,
Feb 13, 2012, 4:45:56 PM2/13/12
to mapi...@googlegroups.com
This formula is wrong:

> hexByte = hexByte + mid$( "123456789ABCDEF", nybble(i) , 1)

It was wrong to begin with:

> hexByte = hexByte + mid$( "0123456789ABCDEF", nybble(i) , 1 )

but you changed the wrong thing. It should be this instead:

hexByte = hexByte + mid$( "0123456789ABCDEF", nybble(i)+1 , 1)

Nybble () element values range from 0 through 15. That's 16 different
values and your string has only 15 characters.
String indices start at 1, so for a 16 character string they range from 1
through 16.
This means you need to add 1 to get the correct string element. Otherwise,
MapBasic will silently return an empty string when a nibble value is 0.

With the right formula, there's absolutely no reason to append zeroes to
each primary color's code.

Spencer

-----Original Message-----
From: Thoern [mailto:turbo...@hotmail.com]
Sent: Monday, February 13, 2012 5:17 AM
To: MapInfo-L
Subject: [MI-L] Re: polygon color to field

Bill

unread,
Feb 13, 2012, 5:52:13 PM2/13/12
to MapInfo-L

On Feb 13, 2:45 pm, "Spencer Simpson" <ssimp...@baltometro.org> wrote:
> This formula is wrong:
>
> >       hexByte = hexByte + mid$( "123456789ABCDEF", nybble(i) , 1)
>
> It was wrong to begin with:
>
> >       hexByte = hexByte + mid$( "0123456789ABCDEF", nybble(i) , 1 )
>
> but you changed the wrong thing.  It should be this instead:
>
> hexByte = hexByte + mid$( "0123456789ABCDEF", nybble(i)+1 , 1)
>
> Nybble () element values range from 0 through 15.  That's 16 different
> values and your string has only 15 characters.
> String indices start at 1, so for a 16 character string they range from 1
> through 16.
> This means you need to add 1 to get the correct string element.   Otherwise,
> MapBasic will silently return an empty string when a nibble value is 0.
>
> With the right formula, there's absolutely no reason to append zeroes to
> each primary color's code.


Just wanted to point out that in the *original* original that was
posted Jan 8th, the formula was right and you don't have to worry
about specifically adding "0"'s; they take care of themselves. The
operation converts a decimal byte (a smallint in the range 0 to 255)
to hexadecimal was wrapped up as a self-contained function. You could
just copy the whole function into your code and never need to fool
around with its innards. (unless you are trying to work out how it
works. In that case you need to literally take it apart and put it
back together again.

Here's that function again:

Function toHexByte( byval decByte as smallint ) as string
Dim hexByte as string, nybble(2) as smallint,i as integer
If decByte > &h100 then
note "value out of range 0 - 255"
Exit function
End if

nybble(2) = decByte \ &h10
nybble(1) = decByte mod &h10
For i = 1 to 2
hexByte = hexByte
+ mid$( "0123456789ABCDEF", nybble(i) , 1 )

Thoern

unread,
Feb 14, 2012, 6:47:08 AM2/14/12
to MapInfo-L
Aha, I think Spencer got was on target, the org function translated to
E instead of F what I recall when testing it, one step was missing so
the +1 in there would do the trick I belive.
I figured it was some indexing array thing.
hexByte = hexByte + mid$( "0123456789ABCDEF", nybble(i)+1 , 1)

Anyhow using the function on a whole table turned out to be about as
slow as the vb thing I did before. But since one do not usally need e
unique color for every row (thematisation of a column values more
common)
one can do some grouping first and speed up the process.

Goood job Guys!
Reply all
Reply to author
Forward
0 new messages