Sunday, February 26, 2017

Drawing buildings/Roads on OpenStreetMap

I used to update OpenStreeMap. One of the most headache thing is that my drawing skill is horrible. Thus far, I can only draw simple roads and square buildings. While trying to add a complex building, it strikes my mind that if I could have a overlay on the map and can trace over it just like what we do on paper.

In actual fact, a lot of people also does that. What they wanted to do is actually to put a logo on the window yet allow user to interact on the windows below it. Helow is an application that I used. The name is Custom Desktop Logo 2.0.

It is a simple app you can set the position of the photo to a standard point on the screen or you can specifically place the photo at exactly the right spot. There is a facility to set transparency. The photo must be in a directory alone. If more than one, the app will try to rotate the display of all the photos at a specific interval. Obviously there is a feature to size the photo to a limited dimension (within a range depending on the size of your photo). You can hide the logo if you want. Since it is on top all windows, it can be used on any windows applications.

With the available feature, I can then place the photo (like route maps from NParks). Set the transparency to just distinguishable. Set OpenStreetMap to the appropriate size, adjust the size of the photo to exactly the same size of the map with existing elements (using a slider). The only other thing to do is to trace the lines.

It is impossible to dynamically resize the photo to get more details in sync with the map but it sure helps in the drawing of map features.

I drew the Chestnut Nature Park North using this feature on Google Maps. It wasn't exact copy but at least it resembles the actual drawing and the positioning of the routes are quite close to real.



Friday, February 24, 2017

Barcodes in Filemaker

When you need to print Barcodes in Filemaker, there are various ways to do it. One way is to use the "repetition" in the field. Each repetition represents a bar or blank. Set the width to 1.  Change the background to black if it is a bar. Obviously, you need to systematically convert the text to the specific type of barcodes first in the form of 1 and 0 then transpose it to the repetition field. It takes two extra fields. One to do the conversion, the other one with the repetition is used to display the barcode. Unfortunately you can't have GS1 HRI (Human Readable Integration).

Another method is to generate the barcode from a script. There are implementations available using plugins (because they want to sell the code). I can't find one that is free.

One other methods uses web views to display the barcode by passing a barcode generator site URL with parameters. However, this requires online access.

Yet another method uses data URL to achieve it. The web page that could create the Barcode using Javascript is stored in a hidden layout object. The data URL then reads the content and replaces a specific string in the web page with the text to be displayed in barcode. In the same way the parameters for the Barcode can also be changed. One good example is FMEasyBarcode. Unfortunately the author no longer maintains the code.

The following is an effort to try to do the same thing as David Shim.

First you need to have a webview object that contains the following script

Let([$html=Substitute(GetLayoutObjectAttribute("QRCode";"content"); ["[[VALUE]]"; mytable::userid)];["[[barcodetype]]";"qrcode"]];"data:text/html," & $html)

In layman's term, get the content of the object "QRCode" then substitute "[[VALUE]]" with mytable::userid (field value). Also substitute "[[barcodetype]]" with the barcode type called "qrcode".

In the hidden object, a complete single page HTML with Javascript is pasted into the content.  This HTML page must not have links that refers to local file (e.g script source). It can of course refer to external URL script source. What David Shim did is to copy the uglyfy js (all extra spaces,tabs,CRLF are removed) and paste into a javascript element. This is done to make sure the HTML have the smallest size.

Since the calculation is using Javascript, the replacement script in the webview will effectively change the data to be processed and run upon loading to produce the barcode. Obviously, that web page should work in normal browser.

I have tried the same method with a code39 script JsBarCode from Johan Lindell. It works fine.

One thing to note is that the size of the display is not by the webview.  I tried to add CSS to automatically resize the element but it just don't work. Some barcode does have a parameter to change the size. You will still gets some white space unless you specifically set the CSS to absolute position and define the top and left coordinate of the element.

One irritating thing is that the hidden object size tends to automatically expand if you try to edit it. But it is a small price to pay unless you want to store the HTML is a global field.

There is no script to show except the one line script mentioned above. The web page content is from other authors. I have included their project page for you to see how it works. David Shim's excellent qrcode project is at QRCodeJS.




Monday, February 20, 2017

Life Long Learning

What can a O level second grade passer do? There is no chance to proceed with U or POLY. There is no financial resources to study ITC. But is that all that I could do? Not really.

I am interested in Electronics thus joined the army as a technician. It is the only formal technical training I ever get. While attached to civilians as a Quality Assurance tech, I have chance to contact with automatic testing technology. My superior encourages me to write programs of our own to do automatic testing instead of relying on contractor's program. With some guidance from the contractor, I managed to write the program which performs equally well as the contractor's without even going for any programming training. At that time the programming language is BASIC which is easily understood. If it is C language  then probably I am done for.

After my army service term completes, I have no certificate that is recognized in the civilian world so I worked for a call management company doing outsource work. The procedure is complex so they have documents to assist the call agents. However, the documents are never synchronized. Each person may have a subset of what is available and updating is a headache. By then I have been promoted supervisor (because nobody wants the post) working in Hewlett Packard.

I began to look for standardization. At that time we are using UNIX system as a computer console. I have virtually no access to the system except the filing directory. After reading books on computers, I noticed that there are help files. Help files can be created using an application. I began to learn how to use the application at my own time and managed to create a standard help file with all the information in one place thus achieved standardization.

As time goes along, the UNIX system has been replaced by Microsoft Windows. The help file can still be used but again my customer's superior urge me to do a web based help system. I have virtually no knowledge of web programming but I took up the challenge by studying HTML and Javascript. The result is a simple web based help system.

After that my customer superior become aggressive and wanted to have a interactive web program by using ColdFusion and web server. Again I took up the challenge and studied ColdFusion while actually writing apps. Luckily it is quite easy to learn Coldfusion. In the process I also learned SQL. The result is a CRM system. All these without the company spending a single cent for training.

As we proceed along, there are some redundant servers available for scrap and we took them in. However, since we only have one licence for ColdFusion, it is deemed too expensive to buy more copies of it. Moreover, the web server is a internally hosted by IT department and it costs to maintain it with them. Therefore, we switch to PHP and Apache web server. They are all free.

With the PHP, Apache web server and unlimited supply of MS SQL server (the customer company have signed an unlimited supply of MS SQL server licence), I wrote two separate PHP CRM system in the course of work. It even include a Standalone Queue display system. How much it costs the company? 0 cents except my salary which is not even a skilled technician pay.

In between all the web programming work, there is a need to transfer the CRM data to the customer's legacy system. All the while we are doing manual copy and paste work. I studied the legacy system and noticed that there is a macro programming which can be controlled externally. The result is that I wrote a DLL program that can be called by Javascript using ActiveX that can write into the fields of the legacy system and able to click the buttons available. It saved us extra manpower to manually enter the data. It saved the customer's money but it is actually counter productive for my boss (we charge by the manpower used for the outsourcing). I ended up being the bad guy for my own company.

To amend for that, I began to write utilities to make our people's life easier without having to cut down on manpower. The result is a series of automatic checks to ensure that the data entered is according to specification. It automatically correct the wrong data according to specification. It even includes an automatic quotation program. We invested a bit and added an automatic SMS and email facility. It was the peak of my programming era with two additional manpower under my charge.

The work also requires reporting system. So, I wrote a series of web reporting system and produce summaries including charts. I even created 6 sigma charts at the customer's request. There is a excel based summery report which is so complex that I have to write macros to do thousands of distinct summary calculations till I myself am amazed to how I actually achieved it.

After my boss have to quit the outsource contract due to difficult customer demands, I become jobless. The customer manager wanted me to sign on with the other outsource company who took over. I declined as I am still loyal to my ex company. Also, it is due to the same customer manager that my boss quits the contract.

Again without formal training, my skills are useless. After two years my ex boss started a new business as a authorized repair agent for Apple handphone and Mac. He contacted me after one year of opening business and request my help to automate the system. I agreed without actually knowing the system used. It turned out that they are all using Mac and iPad. Moreover, the programming tool used is FileMaker. The actual task is to automate between their system and Apple web services.

Being completely new to all three system, I could not promise my boss but he is willing to spend 6 months of time (1/2 day part time) to try achieve it. In the end, I learned how to use a MacBook to write programs with Filemaker and is able to communicate with Apple web services using CURL on Filemaker. The result is a total success without even going for formal training.

I am currently writing Filemaker programs on ad hoc freelance basis for my boss and there is no other new programming challenges but I am still eager to learn new things.

In my free time, I started to cycle and walk around Singapore as an exercise. While exercising I saw flowers and plants that  I cannot even name it. I started to take pictures of plants and try to find their names. In the process I joined iNaturalist and Project Noah and a number of Facebook groups which allow others to help identify nature creatures. I began to take animals and insect photos too. it is a total new "hobby" and I again learned tremendously on this area about plant and animal kingdom. The result is that I walked all over Singapore to places which I have never been and accumulated around 17,000 photos with 2600 plus distinct species (including overseas).

I have created two Blogger blogs one each on plants (Plants in Singapore) and animals (Fauna Singapore) and duplicates them in WordPress webs. After all, what I learned could be useful for others too. I also shared some of my technical skills in this blog too (Everything Jonathan).

While trying to exercise, I encountered problems finding PCN paths. NParks did have a map but it is just a plain map. It did not tell me whether the path goes above or below roads and I have a problem whenever it switch to the other side of road and did not mark it properly (in early days). I have created a map on Google Map to show all these information and other helpful info necessary to have a seamless connectivity between PCNs (New PCN on Bikes). As of to date it has 360,000 plus views.

In the process of creating maps, I learned the skills about GeoTagging. I learned to use different tools to create custom layouts. I learned to tag photo with Geolocation in sync with GPX routes data. It all started just for fun but I learned.

What I have achieved in learning is plenty although it is not recognized by other companies. I am proud of what I did and believes that learning is never redundant in life. There is a Chinese saying "活到老学到老". Learning never ends.







Thursday, February 16, 2017

Filemaker Xpath

While doing communications with Apple GSX, I have to constantly receive XML from GSX. Filemaker does not have functions that handle XML in variables.  Normally, I would use BaseElements plugin function BE_XPath to do the node extraction. But due to its functionality, BE_Xpah treats nodes differently. If there is only one node with a specific node name, it can easily be extracted by using "//mynode". If there is multiple nodes with the same node name then it is a issue. You must use a array style like "//mynode[x]" to get the correct value.

If the XML format is always constant, there is no problem. However, if the XML returned can be one or more nodes of the same name, it is an issue. It ended up that I have to check whether there is multiple node of the same name by trying to parse "//mynode[x]" first to see it has a value then go to the appropriate routine to extract the single or multiple nodes. It is a hassle. Moreover, the script needs the BaseElements plugin. Filemaker Go does not have the capability to use Plugins.

I tried to lookup for scripts that is available in the internet. There are some but its codes are a bit too complicated to comprehend. It may be due to efficiency, they try to use as little script steps as possible to achieve results. Many resort to use "Evaluate" function. I tried as far as possible to avoid using "Evaluate" thus do not want to use it.

Fortunately, two of the scripts uses the same functionality provided by Andy Knasinsky (http://www.briandunning.com/cf/1). It triggers my mind that I could use the same method to extract nodes. I don't have Filemaker Pro Advanced so cannot copy the custom function. Therefore, I start doing my own script.

To start off, I use the same convention of defining the Xpath. The convention is like this "//mynode[x]". It is an array like node name that starts with "//". I will then have to detect whether there is a "[x]" defined. Filemaker has a function called "position". The syntax is as belows

Position[text;searchstring;start; occurrence]

Now if there is no "[x]" defined then I just set "occurrence" to one else get the value of "x" as "occurrence" value. Since "Position" always requires a "start" and "occurrence", The x value is useful to define which instance the node name occurs. Both the start node and end node position can be extracted this way.

With the use of "Middle" function, I am then able to define the exact position of the node value and extract it.

The following is the code. I can't copy and paste as FMP does not have the capability of copy and past the script to text. I do screen capture instead. The script name is "GetNode".

Well, life is not as simple. There will be instances where the same node name appears inside other node. Therefore, it is necessary to define the specific path to the node hence the term "Xpath".

It turned out that this is made easy by the above script. Since the above script is just text manipulation, it can actually retrieve the other child nodes. The syntax of Xpath is like "//node1/node2". It can be more than two and with array like syntax.

I just break up the nodes then loop it in sequence. For example, first I get "node1" then retrieve the node value (including child nodes). Then, I get "node2" based on node1 result. If there is a third child node, then I get the node2 result and look for the node value. In this way, I can get any value from the XML. Below is the script. I name it as "GetPath"



You can just do "Execute Script" and call the "GetPath" script. The script parameter will be
your xml and the xpath separated by a Filemaker carriage return symbol. You will then get the ScriptResult to get the node value.

There is a script in the above script named "Remove Subnode". This script is a result of having an XML that have subnodes that have nodenames same as the root node. If the subnode is above the root node of the same name, the subnode value gets extracted instead. It is, therefore, important to remove the subnodes as the path does not point to the subnode.


After doing the script, I felt that it is still very troublesome if I were to pull a list of values from the XML. A list script is written just to do this. The parameter supplied is the XML, the specific path, and the list of nodes that I want to get. An interesting point is that there is a need to get one or more subnodes in the list. Therefore, I set the node name with an extra "[]" to indicate that it is a subnode. It will then pull the subnode XML as value.
Ignore the Base64 comment as I though the list might be interrupted by the delimiter. It turned up that Base64 adds more trouble. Then I realize that I must compact the XML by removing all CR, LF, TAB, and extra spaces. This means that the CR delimiter is not found in the data itself thus abandoned the idea.



I make no effort to combine the script steps so that it will be easy to read by any novice. Any how, the script should not be used for XML that is tens of thousands of lines long. Try to "compress" the scripts if you need to extract large number of data from XML. It is not within my scope to show you how to use one script line to do complex calculations.

By the way, the XML has to be well formed and error free.


Tuesday, February 07, 2017

Abortion

A lot of people said that the Bible does not say anything about abortion. Indeed there is no specific mention of abortion as the population before 1st century is sparse. In today's world, the population is 7.4 billion as at August 2016 (Wikipedia). Heavy pollution occurs in hugely populated cities. More and more forests have been cleared for human habitation and food cultivation. More species have gone extinct. What then is the Christian point of view in abortion.

Roman Catholic prohibits abortion. They probably based on  Exodus 21:23, Deut 5:17, Gen 25:21-22, Psalm 22:9-10, Psalm 139:13-16, Psalm 22:10-11. It is valid during the 1st century.

Gen 1:28. God created man to subdue and dominate over God's other creation. Does God create plants and animals so that human can destroy them?

Deut 22:6 talks about caring for the birds. You take the eggs but you don't kill the mother.

Leviticus 25:1-55 talks in length about Sabbatical year. Why is it so? Why the land need to rest?

Exodus 23:10-11 talks about letting other animals to eat.

Leviticus 19:9-10 talks about leaving some for the poor and desolate. Why not leave some for other plants and animals?

The above quotes has no relationship to abortion. What is portrayed is the need to maintain balance with the world we live in. We look at human as more important than environment. We multiply so much so that nature have to give way to support human. This is not what "subdue and dominate" means.

In our effort to support humans, we destroy vast stretches of forest. We produced vast amounts of rubbish. We pollute many rivers and seas. We over fished. We don't allow earth to replenish itself. Is this what the Bible taught us to do?

The only way to live in balance with environment is to control the human population.

Abortion is not the best way to control human population.  The best way is contraception. Abortion comes about due to bad human behavior and ignorance. There is no need for abortion if the proper preventive actions were taken. But due to unforeseen circumstances, there is a need for abortion. It must not be a norm. It should be under exceptions.

There are a lot of arguments about at which stage of pregnancy should abortions be prohibited. I think it should be very early stage. It is cruel to abort when the baby is well formed.